【问题标题】:Cannot close Activity while AsyncTask is not finishedAsyncTask 未完成时无法关闭 Activity
【发布时间】:2014-06-10 20:31:37
【问题描述】:

我的Activity 中有一个AsyncTask。在AsyncTaskdoInBackground(Object[]) 方法中,我执行网络操作,使用HTTP POST 方法将一些数据发送到服务器,接收响应,然后在其onPostExecute(Object) 方法中将响应发送到Service 和那么所有的工作都是从Service 执行的。问题是:在AsyncTask 完成之前,我无法关闭ActivityActivity 只是冻结,直到 AsyncTask 完成。有时,如果AsyncTask 需要更多时间来完成,屏幕会变黑并保持这种状态,直到AsyncTask 完成。这是为什么?如何避免这种情况?我曾尝试在ActivityonStop() 方法中调用AsyncTaskcancel(boolean),但它仍然执行相同的行为。

编辑:我的AsyncTask 代码:

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 的响应的类。这就是我在ActivityService 之间进行通信的方式。

我用这个代码开始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);
                /** ... **/
            }
        });
        /** ...  **/
    }
    /** ... **/
}

【问题讨论】:

  • 您有 99.999% 的机会错误地实现了 AsyncTask。您必须显示您的代码,以便人们可以检查其中有什么问题。
  • 正如@Budius 所说,这不正常。似乎您正在锁定您的线程,这正是不应该发生的事情。
  • 我强烈建议您在您的服务中发出 POST 请求,因为您已经有了一个。它将使您的代码更简单,并将其与 Activity 生命周期完全隔离。
  • 我在上面的问题中添加了我的AsyncTask类的代码!
  • 你能在你开始任务的地方添加代码吗?

标签: java android service android-asynctask android-activity


【解决方案1】:

我已经解决了这个问题。 Activity 冻结了,因为我要从这个返回的 Activity 也在其 onResume() 方法中使用 AsyncTask,所以它必须等到关闭 Activity 的第一个任务完成之前执行自己的任务,这导致 UI 冻结。现在我使用executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Object[] 能够并行运行多个任务,而不是串联(一个接一个)。

【讨论】:

    猜你喜欢
    • 2017-12-16
    • 1970-01-01
    • 2014-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多