Je travaille sur du code qui va extraire des informations JSON de Facebook et les placer dans une vue EditText. Le problème que je rencontre est que puisque la fonction que j'appelle pour récupérer les données est une fonction Async, les données sont récupérées APRÈS que ma fonction onCreate se termine pour mon activité, donc le texte ne peut pas être mis à jour car il est nul . Comment puis-je m'assurer que ma méthode OnCreate ne se termine pas tant que les données ne sont pas récupérées?OnCreate se termine avant que les données puissent être récupérées de manière asynchrone
Voici ma classe d'activité:
public class PersonalInfoMain extends AppCompatActivity implements GraphService.OnDownloadComplete {
public EditText mName;
public String name;
String mValue, mField;
private static final String TAG = "PersonalInfoMain";
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate: starts");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_personal_info_main);
mName = (EditText) findViewById(R.id.editText_name);
//Calling GraphService class
GraphService mGraphService = new GraphService(this);
mField = "name";
mGraphService.execute(mField);
mName.setText(name);
}
}
//My Callback function located in the same activity:
@Override
public void onDownloadComplete(String s) {
name = s;
}
Voici ma classe j'étiquetée GraphService pour tirer des informations de Facebook:
public class GraphService extends AsyncTask<String, Void, String>{
private static final String TAG = "GraphService";
private String mField;
private String mValue;
private final OnDownloadComplete mCallback;
public interface OnDownloadComplete{
void onDownloadComplete(String data);
}
public GraphService(OnDownloadComplete callback){
mCallback = callback;
}
@Override
public String doInBackground(final String... params) {
Log.d(TAG, "doInBackground: starts");
mField = params[0];
//Beginning of Facebook implementation
GraphRequest request = GraphRequest.newMeRequest(
AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
@Override
public void onCompleted(JSONObject object, GraphResponse response) {
try {
mValue = object.getString(mField);
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
);
Bundle parameters = new Bundle();
parameters.putString("fields", mField);
request.setParameters(parameters);
request.executeAsync();
return mValue;
}
@Override
protected void onPostExecute(String s) {
if(mCallback != null){
mCallback.onDownloadComplete(s);
}
}
My Android Monitor affiche ce flux de travail:
D/MainActivity: onCreate: starts
D/MainActivity: isLoggedIn: starts
D/MainActivity: isLoggedIn: ends
D/MainActivity: onCreate: ends
D/PersonalInfoMain: onCreate: starts
D/PersonalInfoMain: onCreate: name = null
D/GraphService: doInBackground: starts
D/PersonalInfoMain: onCreate: ends
D/PersonalInfoMain: onResume: starts
D/PersonalInfoMain: onResume: name = null
D/GraphService: doInBackground: ends
D/PersonalInfoMain: onResume: ends
D/GraphService: onPostExecute: starts
D/PersonalInfoMain: onDownloadComplete: starts
D/PersonalInfoMain: onDownloadComplete: ends
D/GraphService: onPostExecute: ends
D/GraphService: onCompleted: starts, JSON object = {"name":"Tom"}, response = {"name":"Tom"}
D/GraphService: onCompleted: json object:{"name":"Tom"}
D/GraphService: onCompleted: ends
Comme vous pouvez le voir, ma méthode .setText() dans mon activité la définit sur une valeur null car la tâche asynchrone (méthode onCompleted()) n'a pas encore retourné les données. Comment puis-je m'assurer que ma méthode OnCreate ne se termine pas tant que les données ne sont pas récupérées?
J'apprécierais n'importe quel conseil.
Merci.
Salut Sunil, J'ai toujours entendu dire que les actions courtes comme une requête réseau doivent être appelées de manière asynchrone. Pouvez-vous expliquer pourquoi je ne devrais pas faire ça? J'ai essayé votre code et il ne met toujours pas à jour mName car le code de récupération JSON est appelé après la fin de la fonction onDownloadComplete (comme vous pouvez le voir dans le Logcat) – Ozzy
Oui je viens de découvrir que vous faites de nouveau GraphRequest asynchrone à l'intérieur de doInBackground, dans ce cas, vous appelez return avant même que vous obteniez le résultat de la requête. Ici, vous n'avez pas besoin d'AsyncTask car vous pouvez appeler directement GraphRequest. –