OnCreate在可以异步检索数据之前结束
问题描述:
我正在研究一些代码,它将从Facebook中提取JSON信息并将其放入EditText视图中。我遇到的问题是因为我调用来检索数据的函数是一个异步函数,在我的活动的onCreate函数结束后正在检索数据,所以文本无法更新,因为当它为空。 我怎样才能确保我的OnCreate方法不会结束,直到数据被检索?OnCreate在可以异步检索数据之前结束
这里是我的活动课:
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;
}
这里是我的I类标记GraphService从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);
}
}
我的Android监视器显示该工作流程:
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
正如您所看到的,我的活动中的.setText()方法将其设置为由于Async任务(onCompleted()方法)尚未返回数据,因此为空值。 我怎样才能确保我的OnCreate方法不会结束,直到数据被检索?
我将不胜感激任何意见。
谢谢。
答
你不能和你不应该因为你正在做异步网络请求。一旦您需要网络呼叫的数据,最好调用setText方法。
//我的回调函数位于相同的活动:
@Override
public void onDownloadComplete(String s) {
mName.setText(s);
}
答
也许你可以尝试将代码从onDownloadComplete()移动到onPostExecute()。我个人不认为这是需要使用
公共接口OnDownloadComplete {
void onDownloadComplete(String data);
}
这里。
执行方法doInBackground()后,它的结果(mValue)将作为s传递给onPostExecute(String s)。
在onPostExecute()中,您可以更新您的UI。
这是我的第一个答案。如果有什么不对,请告诉我。
嗨Sunil,我总是听说像网络请求这样的短操作应该异步调用。你能解释为什么我不应该这样做吗? 我试过了你的代码,它仍然不更新mName,因为在onDownloadComplete函数结束之后调用了JSON检索代码(正如你在Logcat中看到的那样) – Ozzy
是的,我刚刚发现你又一次异步GraphRequest在doInBackground中,所以在这种情况下,即使在从请求中获得结果之前,也可以调用return。在这里你不需要AsyncTask,因为你可以直接调用GraphRequest。 –