简体   繁体   中英

Cannot close Activity while AsyncTask is not finished

I have an AsyncTask running in my Activity . In that AsyncTask 's doInBackground(Object[]) method I perform a network operation which sends some data to a server using HTTP POST method, receives a response, then in its onPostExecute(Object) method it sends that response to a Service and then all the job is performed from the Service . The problem is: I can't close the Activity until the AsyncTask is finished. The Activity just freezes until the AsyncTask completes. Sometimes, if the AsyncTask needs more time to complete, the screen becomes black and stays like that until the AsyncTask is finished. Why is that? How to avoid this? I have tried calling to AsyncTask 's cancel(boolean) in Activity 's onStop() method but it still performed the same behaviour.

EDIT: 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 class is a class that handles the response from the Service . This is how I made the communication between the Activity and the Service .

I start the AsyncTask with this code:

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);
                /** ... **/
            }
        });
        /** ...  **/
    }
    /** ... **/
}

I've fixed this issue. The Activity was freezing because the Activity I am going back to from this one is also using AsyncTask in its onResume() method, so it had to wait until the first task from the closed Activity is done before executing its own task and this caused the freeze of the UI. Now I am using executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Object[] to be able to run multiple tasks parallel, not in series (one by one).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM