2017-05-13 3 views
1

ich mit einer API zur Interaktion bin versucht und festzustellen, ob der Benutzer auf dieser API vorhanden ist, indem die JSON Antwort Überprüfung von aktueller E-Mail zu vergleichen (gespeichert in SharedPrefs) mit den E-Mail von API zurückgegeben. Wenn der Benutzer existiert, wird ein Flag true gesetzt, damit die App keine POST-Anfrage sendet, um den neuen Benutzer zu speichern, und wenn es false ist, wird der Benutzer in API gespeichert.boolean Flag ist immer falsch

Also, das ist die UEC (UserExistenceChecker) Klasse

public class UEC extends AppCompatActivity { 

List<SavePlace> userInfo; 

String name; 
boolean flag; 
SharedPreferences sharedPref; 

public UEC(SharedPreferences sharedPref){ 
    this.sharedPref = sharedPref; 
} 

@Override 
protected void onCreate(@Nullable Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
} 

public boolean checkIfUserExists() { 

    email = sharedPref.getString("userEmail", ""); 

    Retrofit retrofitCheckUser = ApiClientSavePlace.getClient(); 
    ApiInterfaceSavePlace apiInterfaceSavePlace = retrofitCheckUser.create(ApiInterfaceSavePlace.class); 
    final Call<List<SavePlace>> checkUser = apiInterfaceSavePlace.getSavePlaces(); 

    checkUser.enqueue(new Callback<List<SavePlace>>() { 
     @Override 
     public void onResponse(Call<List<SavePlace>> call, Response<List<SavePlace>> response) { 
      userInfo = response.body(); 
      try { 
       if(userInfo.size()!=0){ 
        for (int i = 0; i <= userInfo.size(); i++) { 
         String emailReturned = userInfo.get(i).getEmail(); 
         Log.d("response", "email returned: " + emailReturned); 
         Log.d("sharedpref", "email: " + email); 
         if (emailReturned.equals(email)) { 
         Log.d("response:", "email match?: " + emailReturned.equals(email)); 
          flag = true; 
          SharedPreferences.Editor editor = sharedPref.edit(); 
          editor.putInt("userID", userInfo.get(i).getId()); 
          Log.d("ID returned", String.valueOf(userInfo.get(i).getId())); 
          editor.apply(); 
          break; 
         } 
        } 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 

     @Override 
     public void onFailure(Call<List<SavePlace>> call, Throwable throwable) { 
      Log.d("RESPONSE", "FAILED CHECKING USER ID/SOMETHING HAPPENED"); 
     } 
    }); 
    return flag; 
} 

} 

In dieser Klasse habe ich ein boolean Flag mit Standardwert falsch

gemacht und das ist, wie ich rufen Sie die Methode checkIfUserExists() von MainActivity.java

public class MainActivity{ 

SharedPreferences sharedPref = 
PreferenceManager.getDefaultSharedPreferences(getBaseContext()); 

    UEC uec = new UEC(sharedPref); 
    boolean userExists = uec.checkIfUserExists(); 
    if (userExists) { 
     Log.d("USERSTATUS", String.valueOf(sharedPref.getInt("userID", 0))); 
    } else { 
     Log.d("USERSTATUS", "FALSE:DOESNT EXIST"); 
     Log.d("USERSTATUS", String.valueOf(sharedPref.getInt("userID", 0))); 
    } 
} 

Nun ist das Problem, dass nach den Protokollen, sonst Zustand ist immer wahr weil die Flagge ist immer falsch obwohl ich es wahr in checkIfUserExists bin Einrichtung () Methode.

und das Interessante an Protokolle ist, dass diese

05-13 15:27:54.278 1613-1613/xyz.gautamhans.locus D/USERSTATUS: FALSE:DOESNT 
EXIST 
05-13 15:27:54.278 1613-1613/xyz.gautamhans.locus D/USERSTATUS: 12 

zuerst kommt und dann kommt dies in Protokollen nach oben log

05-13 15:27:55.746 1613-1613/xyz.gautamhans.locus D/response: email 
returned: [email protected] 
05-13 15:27:55.749 1613-1613/xyz.gautamhans.locus D/sharedpref: email: 
[email protected] 
05-13 15:27:55.749 1613-1613/xyz.gautamhans.locus D/response: email 
returned: [email protected] 
05-13 15:27:55.749 1613-1613/xyz.gautamhans.locus D/sharedpref: email: 
[email protected] 
05-13 15:27:55.749 1613-1613/xyz.gautamhans.locus D/response: email match?: 
true 
05-13 15:27:55.749 1613-1613/xyz.gautamhans.locus D/ID returned: 12 

was bedeutet, dass sie die E-Mail erkannt und stellen Sie die sharedpref aber die Flagge ist immer noch falsch.

Antwort

0

Das Verhalten ist auf Asynchrone Ausführung von checkUser.enqueue(new Callback<List<SavePlace>>() fällig. Also, wenn Sie dieses diese Methode von checkIfUserExists() aufrufen, Ihre Ausführungs-Thread wird nicht für checkUser.enqueue() warten zu vervollständigen. Stattdessen springt es sofort zur nächsten Zeile und gibt den aktuellen Flag-Wert zurück, der falsch ist. checkUser.enqueue() wird in einem Hintergrundthread ausgeführt und Sie erhalten das Ergebnis in onResponse() Methode. Das Verhalten ist gemäß Ihrem Code korrekt. Versuchen Sie, die Szenarien asynchron zu behandeln, wie dies für einen Netzwerkaufruf empfohlen wird.

+0

Ja, das verstehe ich jetzt. Vielen Dank. Gibt es eine mögliche Lösung für dieses Problem, die Sie sich vorstellen können? – mnmncp

1

Aus einem kurzen Blick auf Ihren Code sieht es so aus, als ob die Enqueue-Methode bewirkt, dass der Boolesche Wert erst nach dem Aufruf der Methode checkIfUserExists() in true geändert wird.

Dies ist, was Sie in Ihren Protokollen sehen, aufgrund der asynchronen Natur der Enqueue-Methode, wird der gesamte Code innerhalb Ihrer onResponse() und onFailure() nur nach allem anderen in einem Hintergrund-Thread ausgeführt.

Um dies zu vermeiden, könnten Sie eine Callback-Methode implementieren, so dass Sie die Methode immer dann aufrufen, wenn die Methode onResponse() beendet ist, um zu überprüfen, ob der Benutzer existiert.Im folgenden Code ist die Callback-Methode onUserExists(), die das wahre boolesche Flag ersetzt, und ich habe auch eine else-Anweisung eingefügt, wenn der Benutzer nicht existiert, der einen zweiten Callback auslöst, die onUserDoesNotExist()-Methode. Diese Callback-Methoden lösen den Code in der MainActivity innerhalb der Methoden onUserExists() und onUserDoesNotExist() dort aus.

public void checkIfUserExists(OnUserExistsCallback onUserExistsCallback) { 

    email = sharedPref.getString("userEmail", ""); 

    Retrofit retrofitCheckUser = ApiClientSavePlace.getClient(); 
    ApiInterfaceSavePlace apiInterfaceSavePlace = retrofitCheckUser.create(ApiInterfaceSavePlace.class); 
    final Call<List<SavePlace>> checkUser = apiInterfaceSavePlace.getSavePlaces(); 
    OnUserExistsCallback callback = onUserExistsCallback; 
    checkUser.enqueue(new Callback<List<SavePlace>>() { 
     @Override 
     public void onResponse(Call<List<SavePlace>> call, Response<List<SavePlace>> response) { 
      userInfo = response.body(); 
      try { 
       if(userInfo.size()!=0){ 
        for (int i = 0; i <= userInfo.size(); i++) { 
         String emailReturned = userInfo.get(i).getEmail(); 
         Log.d("response", "email returned: " + emailReturned); 
         Log.d("sharedpref", "email: " + email); 
         if (emailReturned.equals(email)) { 
         Log.d("response:", "email match?: " + emailReturned.equals(email)); 
          SharedPreferences.Editor editor = sharedPref.edit(); 
          editor.putInt("userID", userInfo.get(i).getId()); 
          Log.d("ID returned", String.valueOf(userInfo.get(i).getId())); 
          editor.apply(); 
          callback.onUserExists(); 
          break; 
         } else { 
          callback.onUserDoesNotExist(); 
         } 
        } 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 

     @Override 
     public void onFailure(Call<List<SavePlace>> call, Throwable throwable) { 
      Log.d("RESPONSE", "FAILED CHECKING USER ID/SOMETHING HAPPENED"); 
     } 
    }); 
    return flag; 
} 

Damit dies funktioniert, müssen Sie die OnUserExistsCallback-Schnittstelle erstellen.

Endlich sieht Ihre MainActivity jetzt so aus.

Nicht sicher, ob dies erfolgreich kompiliert und ausgeführt wird, da ich diesen Code nicht selbst ausgeführt habe. Hoffentlich wird es und wird es dein Problem lösen.

+0

Hallo. Danke für die Antwort. Ich habe Probleme bei der Implementierung Ihrer Lösung. siehe diesen Screenshot: http://i.imgur.com/Rp7IPr4.png – mnmncp

+0

@mnmncp zuerst 'onUserExistsCallback' sollte Großbuchstabe 'O' nicht Kleinbuchstabe 'O' sein. –

+0

Ihr Interface-Name hat auch Kleinbuchstaben 'o' am Anfang – mnmncp

0

Das Problem ist, dass Sie mit asynchronen Funktionsaufruf handelt, wenn Sie diese Methode aufrufen

uec.checkIfUserExists(); 

der Code innerhalb dieser Funktion in gewohnter Weise, bis die Zeile ausgeführt wird, wo Sie Ihre api Anruf hier

das macht einen Web-API-Aufruf im Hintergrund Thread und Ihre Funktion führt auf normale Weise und kehrt zurück, was bedeutet, dass Sie Flag als falscher Wert erhalten. und wenn die Hintergrundaufgabe dann den Code in

public void onResponse() 

Verfahren beendet ist ausgeführt, die eine Callback-Methode ist und Sie Ihre Werte mit echten Flagge.

Lösung

Sie für Ihre api Anruf existieren alle Prüfungen auf Benutzer abzuschließen warten soll, und führen Sie dann oder nicht. So ist ein einfacher Weg, Ihre Benutzer-Check in OnResponse() Callback-Methode selbst zu setzen.

Und wenn Sie wollen, dass es in Ihrer Tätigkeit behandeln oder fragmentieren Sie Ihre eigene Callback-Methode erstellen und übergibt es an checkIfUserExists();

So etwas wie diese

public interface MyInterface{ 
    public void onCallback(boolean isUserExists); 
} 

und in Ihrer Tätigkeit

uec.checkIfUserExists(
    new MyInterface(){ 
     @Override 
     public void onCallback(boolean isUserExists){ 
      if (isUserExists) { 
       //your code 
      } 
      else{ 
       //your code 
      } 
     } 
    } 
); 

Nehmen Sie Änderungen an der Methode checkIfUserExists() vor, wie diese

public void checkIfUserExists(final MyInterface myInterface) { 
    //your code 
    checkUser.enqueue(new Callback<List<SavePlace>>(final MyInterface myInterface) { 
     @Override 
     public void onResponse(Call<List<SavePlace>> call, Response<List<SavePlace>> response) { 
      userInfo = response.body(); 
      try { 
       //your code 
        if (emailReturned.equals(email)) { 
         flag = true; 
        } 
        //pass your flag to callback method here. 
        myInterface.onCallback(flag); 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 

     @Override 
     public void onFailure(Call<List<SavePlace>> call, Throwable throwable) { 
      //Handle failure 
     } 
    }); 
} 
+0

danke für die Antwort. Können Sie mir sagen, wie ich die Schnittstelle verwenden soll, um die CallBack-Methode in checkIfUserExists() oder Enqueue-Methode aufzurufen? – mnmncp

+0

Überprüfen Sie meine bearbeitete Antwort – Fahadsk

Verwandte Themen