我有在AsyncTask中将请求发送到REST API的代码。
另外,我在preExecute()
中有一个ProgressDialog初始化,在postExecute()
中有它的解除。
我希望ProgressDialog显示一个不确定的微调器(您知道,正在加载动画),但是我也需要得到一个结果。 get()
阻塞了我在其中调用主线程的情况-这种情况的解决方法是什么?
主线程(主要活动)
LoginTask task_login = new LoginTask();
AsyncTask<String, Void, JSONObject> response = task_login.execute(et_username.getText().toString(), et_password.getText().toString());
try {
JSONObject json = response.get();
Toast.makeText(MainActivity.this, json.toString(), Toast.LENGTH_SHORT).show();
} catch (InterruptedException e) {
Toast.makeText(MainActivity.this, "Interrupted.", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
AsyncTask(虚拟doInBackground):
public class LoginTask extends AsyncTask<String, Void, JSONObject> {
private LoginTask self = this;
private ProgressDialog progressDialog;
@Override
protected JSONObject doInBackground(String... params) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(MainActivity.context,
"Logging in...", "");
progressDialog.setButton(DialogInterface.BUTTON_NEUTRAL,
MainActivity.context.getResources().getResourceEntryName(R.string.dialog_button_cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
self.cancel(true);
}
});
}
@Override
protected void onPostExecute(JSONObject jsonObject) {
super.onPostExecute(jsonObject);
progressDialog.dismiss();
}
}
答案 0 :(得分:1)
您可以使用AsyncTask的onProgressUpdate()方法在UI线程上执行操作(例如显示或更新加载动画),而doInBackGround()在另一线程上执行后台工作。
基本上,您从doInBackGround()中调用publishProgress()方法,该方法又调用onProgressUpdate()。
查看AsyncTask上的Android reference page为例。
答案 1 :(得分:0)
1-您可以使用回调方法。 但是请记住,您应该在主线程中调用它。
2-您可以使用LocalBroadcastManager
来通过Intent
发送结果。
3-我认为您可能想在更可靠的应用程序消息传递库中使用。我经常使用的一个示例是EventBus
。
答案 2 :(得分:0)
请查看AsyncTask https://developer.android.com/reference/android/os/AsyncTask#usage
的用法有一个回调函数onPostExecute
,该函数返回(作为参数)您请求的值:
private class RestTask extends AsyncTask<Object, Object, String> {
protected String doInBackground(Object... args) {
// this happend on background thread
return downloadData();
}
protected void onPreExecute() {
// this happend on UI thread
showSpinner();
}
protected void onPostExecute(String result) {
// this happend on UI thread
hideSpinner();
doSomethingWithDownloadResult(result);
}
}
用法:
new RestTask().execute()
在您编辑问题时,这是
try {
JSONObject json = response.get();
Toast.makeText(MainActivity.this, json.toString(), Toast.LENGTH_SHORT).show();
} catch (InterruptedException e) {
Toast.makeText(MainActivity.this, "Interrupted.", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
应该在以前的Tasks onPostExecute
方法中调用,这样,您将不会使用get
方法阻止UI等待登录结果。