我有以下代码:
这里是指向asyncHttp的doucmentation的链接: Link
这就是调用登录任务的原因:
mAuthTask = new UserLoginTask();
mAuthTask.execute((Void) null);
这是android模板活动提供的异步任务:
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
@Override
protected Boolean doInBackground(Void... params) {
// TODO: attempt authentication against a network service.
Network.login(mEmail, mPassword, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers,
byte[] responseBody) {
if (statusCode == 200) {
// Successfully got a response
for (int i = 0; i < headers.length; i++) {
if (headers[i].getName().equalsIgnoreCase("token")) {
// Set the token to the received value
Network.SetToken(headers[i].getValue());
// >>>>>>> return true; <<<<<<<<<
}
}
}
// >>>>> return false <<<<<<<<<<<<
}
@Override
public void onFailure(int statusCode, Header[] headers,
byte[] responseBody, Throwable error) {
// Response failed :(
// >>>>>>>>>>>>>>>>>> return false <<<<<<<<<<<<<
}
});
// TODO: register the new account here.
return true;
}
@Override
protected void onPostExecute(final Boolean success) {
mAuthTask = null;
showProgress(false);
if (success) {
finish();
} else {
mPasswordView
.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
如何从AsyncHttpResponseHandler中返回true或false,然后将该值返回到异步任务?这样它就可以成功执行其on post方法。
我只能想到设置变量然后阻塞它。但是那个失败主义者认为它是异步的,我宁愿远离那个。
答案 0 :(得分:1)
来自开发者文档
AsyncTask可以正确,轻松地使用UI线程。此类允许执行后台操作并在UI线程上发布结果,而无需操纵线程和/或处理程序.AsyncTask旨在成为Thread和Handler的辅助类,并不构成通用的线程框架。理想情况下,AsyncTasks应该用于短操作(最多几秒钟。)
现在说如果你真的想在onPostExecute
完成,你可以这样做
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
@Override
protected Boolean doInBackground(Void... params) {
// TODO: attempt authentication against a network service.
final ResponseContainer responseContainer = new ResponseContainer();
Network.login(mEmail, mPassword, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers,
byte[] responseBody) {
if (statusCode == 200) {
// Successfully got a response
for (int i = 0; i < headers.length; i++) {
if (headers[i].getName().equalsIgnoreCase("token")) {
// Set the token to the received value
Network.SetToken(headers[i].getValue());
// >>>>>>> return true; <<<<<<<<<
responseContainer.result = true;
}
}
}
// >>>>> return false <<<<<<<<<<<<
responseContainer.result = false;
}
@Override
public void onFailure(int statusCode, Header[] headers,
byte[] responseBody, Throwable error) {
// Response failed :(
// >>>>>>>>>>>>>>>>>> return false <<<<<<<<<<<<<
responseContainer.result = false;
}
});
// TODO: register the new account here.
return responseContainer.result;
}
@Override
protected void onPostExecute(final Boolean success) {
mAuthTask = null;
showProgress(false);
if (success) {
finish();
} else {
mPasswordView
.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
private class ResponseContainer {
public boolean result;
}
}
答案 1 :(得分:0)
当且仅当网络呼叫在其自己的线程上运行时,您可以尝试通过确定网络呼叫使用的线程并使用Thread.join
来阻止doInBackground
来执行此操作。
但是,我不认为你可以保证它,因为你没有指定执行者,并且可以在你给出的代码之外进行更改。所以,如果我有这个问题,我会转换代码并使用AsyncHandler
来响应网络调用的响应,完全避免嵌套的异步操作。像这样:
public void loginUser() {
Network.login(mEmail, mPassword, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers,
byte[] responseBody) {
if (statusCode == 200) {
// Successfully got a response
for (int i = 0; i < headers.length; i++) {
if (headers[i].getName().equalsIgnoreCase("token")) {
// Set the token to the received value
Network.SetToken(headers[i].getValue());
new RegisterUserTask(statusCode, responseBody).execute();
}
}
}
// respond to a failed authentication.
mPasswordView
.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
@Override
public void onFailure(int statusCode, Header[] headers,
byte[] responseBody, Throwable error) {
// Response failed :(
// Show some sort of error.
}
});
}
public class RegisterUserTask extends AsyncTask<Void, Void, Boolean> {
private int statusCode;
private byte[] body;
public RegisterUserTask(int statusCode, byte[] body) {
this.statusCode = statusCode;
this.body = body;
}
@Override
protected Boolean doInBackground(Void... params) {
// TODO: register the new account here.
return true;
}
@Override
protected void onPostExecute(final Boolean success) {
mAuthTask = null;
showProgress(false);
if (success) {
finish();
}
}
}
答案 2 :(得分:0)
Network.login不是已经异步吗?
您可以使用处理程序系统:
private static final int SUCCESS= 0;
private static final int FAIL= 1;
//In your class
private final Handler handler = new Handler() {
@Override
public void handleMessage(final Message msg) {
runOnUiThread(new Runnable() {
@Override
public void run() {
switch (msg.what) {
case SUCCESS:
finish();
break;
case FAIL:
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
break;
default:
break;
}
}
});
}
};
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
@Override
protected Boolean doInBackground(Void... params) {
// TODO: attempt authentication against a network service.
Network.login(mEmail, mPassword, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers,
byte[] responseBody) {
if (statusCode == 200) {
// Successfully got a response
for (int i = 0; i < headers.length; i++) {
if (headers[i].getName().equalsIgnoreCase("token")) {
// Set the token to the received value
Network.SetToken(headers[i].getValue());
handler.sendEmptyMessage(SUCCESS);
}
}
}
// >>>>> return false <<<<<<<<<<<<
handler.sendEmptyMessage(FAIL);
}
@Override
public void onFailure(int statusCode, Header[] headers,
byte[] responseBody, Throwable error) {
// Response failed :(
handler.sendEmptyMessage(FAIL);
// >>>>>>>>>>>>>>>>>> return false <<<<<<<<<<<<<
}
});
// TODO: register the new account here.
return true;
}
@Override
protected void onPostExecute(final Boolean success) {
}
}
但我认为你不必在Network.login中使用asyncTask .. 如果它的同步可能只是一个新的线程?
new Thread() {
@Override
public void run() {
Network.login(...) {
...
}
};
}.start();
答案 3 :(得分:0)
如果我明白你的意思,你的意思是找到一种方法来处理像AsyncTaskCompleted这样的事件并在那里做你的员工。解决方案是定义一个类似WebServiceCallbackProxy的接口:
public interface WebServiceCallbackProxy {
void CallBack(char[] jsonData, String serviceName, boolean isCommunicationSucceed, HttpRequestType reguestType, String serviceTicket);
}
然后在AsyncTask中定义一个实例:
public class AsynServiceCall extends AsyncTask<String, Integer, char[]> {
WebServiceCallbackProxy proxy;
....
public AsynServiceCall(WebServiceCallbackProxy webServiceProxy, ProgressDialog progressDialog) {
this.proxy = webServiceProxy;
}
然后在PostExecute上调用你的CallBackMethod:
protected void onPostExecute(char[] response) {
if (this.progressDialog != null) {
progressDialog.dismiss();
}
if(proxy != null)
proxy.CallBack(response, this.serviceName, this.isCommunicationSucced, this.requestType, this.serivceTicket);
}
这样做,你有一个具有OnCompleted CallBack方法的AsyncTask。