我有一个AsyncTask
运行在我的Activity
。在AsyncTask
的doInBackground(Object[])
方法中,我执行一个网络操作,使用HTTP POST
方法向服务器发送一些数据,接收响应,然后在onPostExecute(Object)
方法中将该响应发送给Service
,然后从Service
执行所有工作。问题是:我不能关闭Activity
,直到AsyncTask
完成。Activity
只是冻结,直到AsyncTask
完成。有时,如果AsyncTask
需要更多的时间来完成,屏幕就会变黑,直到AsyncTask
完成。为什么呢?如何避免这种情况?我尝试在Activity
的onStop()
方法中调用AsyncTask
的cancel(boolean)
,但它仍然执行相同的行为。
编辑:my AsyncTask
code:
private static class PostCommentTask extends AsyncTask<String, Void, String> {
Activity activity;
int status;
Toast indicationMsg;
public PostCommentTask(Context context) {
activity = (Activity) context;
}
private boolean isNetworkAvailable() {
Log.i("ilog", "isNetworkAvailable() called");
ConnectivityManager connManager = (ConnectivityManager) activity.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected() && activeNetworkInfo.isAvailable();
}
protected String doInBackground(String... param) {
if (!isNetworkAvailable()) {
return "";
}
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(param[7]);
String responseBody = "error in PostComment.doInBackground()";
try {
List<NameValuePair> params = new ArrayList<NameValuePair>(7);
params.add(new BasicNameValuePair("somevar", param[0]));
params.add(new BasicNameValuePair("somevar", param[1]));
params.add(new BasicNameValuePair("somevar", param[2]));
params.add(new BasicNameValuePair("somevar", param[3]));
params.add(new BasicNameValuePair("somevar", param[4]));
params.add(new BasicNameValuePair("somevar", param[5]));
params.add(new BasicNameValuePair("somevar", param[6]));
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse response = httpClient.execute(httpPost);
status = response.getStatusLine().getStatusCode();
Log.i("ilog", "response status: " + status);
HttpEntity responseEntity = response.getEntity();
if (responseEntity != null) {
responseBody = EntityUtils.toString(responseEntity);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Log.i("ilog", "Response: " + responseBody);
return responseBody;
}
public void onPostExecute(String responseBody) {
String success = "{"status":"OK"}";
if (responseBody.equals(success) && status == 200){
indicationMsg = Toast.makeText(activity, "Success!!!", Toast.LENGTH_LONG);
CommentsFragment.CommentsHandler commentsHandler = new CommentsFragment.CommentsHandler();
Messenger messenger = new Messenger(commentsHandler);
Intent serviceIntent = new Intent(activity, WindowService.class);
serviceIntent.putExtra("messenger", messenger);
serviceIntent.putExtra("somevar", somevar);
serviceIntent.putExtra("somevar", activity.getIntent().getStringExtra("somevar"));
activity.startService(serviceIntent);
//
}
else
indicationMsg = Toast.makeText(activity, "Failed...", Toast.LENGTH_LONG);
indicationMsg.show();
}
}
CommentsHandler
类是处理来自Service
的响应的类。这就是我如何在Activity
和Service
之间进行通信的。
我用下面的代码开始AsyncTask
:
public static class CommentsFragment extends Fragment {
/** ... **/
@Override
public void onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/** ... **/
Button queryButton = (Button) rootView.findViewById(R.id.query_button);
queryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/** ... **/
new PostCommentTask(activity).execute(somevar, somevar, somevar, somevar, somevar, somevar, somevar, somevar);
/** ... **/
}
});
/** ... **/
}
/** ... **/
}
我已经修复了这个问题。Activity
正在冻结,因为我从这个返回的Activity
也在其onResume()
方法中使用AsyncTask
,所以它必须等到关闭的Activity
的第一个任务完成后才执行自己的任务,这导致了UI的冻结。现在我使用executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Object[]
能够并行运行多个任务,而不是串联(一个接一个)。