5

Here is a sample code which make me a little missing:

package com.leak;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
public class WindowLeakActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    new LeakThread().execute();
}


class LeakThread extends AsyncTask<Void, Void,Void>{

    ProgressDialog dialog;

    @Override
    protected void onPreExecute() {
        dialog=new ProgressDialog(WindowLeakActivity.this);
        dialog.show();
    }

    @Override
    protected Void doInBackground(Void... params) {
        try {
            Thread.sleep(2000);
            finish();
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        //that would be ok
        if(WindowLeakActivity.this!=null && !WindowLeakActivity.this.isFinishing())
            dialog.dismiss();
    }


}}

As you see,I create a LeakThread and finish the WindowLeakActivity at doInBackground()method.

In order to prevent window leak error,I have to check if the Activity has been finished at onPostExecute()method.That make me a little missing.I have following questions:

  1. Is do Activity instance isFinish() check at onPostExecute safe?If my Thread class is not a inner class of Activity.Do I have to check Activity instance is not null at first?
  2. When would Activity instance die?As Activity's lifecycle description,it will terminal when callback call onDestroy().But however,the Activity's Thread is still going.Though it's window been not visible,I can also get it's instance.
  3. If I call the System.gc().Will it collect Activity's instance?

Sorry for my bad description.Thank you for reading my question very much.

user890973
  • 947
  • 2
  • 8
  • 12
  • I know it is not answer but please check this: http://commonsware.com/blog/2010/09/10/asynctask-screen-rotation.html you can find here very nice example how AsyncTask can be handled with all those activity problems. – ania Aug 12 '11 at 01:56
  • Thank you.This is a good and safe AsyncTask template。 – user890973 Aug 12 '11 at 03:54

1 Answers1

2

1) Generally as a rule, avoid using any reference to the activity inside doInBackground(). Managing AsyncTask along with the life cycle of an Activity is tricky at best. Look at this StackOverflow thread for a good discussion on AsyncTask and its pitfalls.

2) You are not in control of when the instance of the activity will die, so don't go about depending on it. The destruction of the instance of the activity depends on several factors, which are determined by the system. So try and ensure that you don't use a reference to the Activity anywhere outside the scope of the activity object itself. You however, do receive a callback when your Activity's execution is about to stop, so make sure you clean up memory there.

3) System.gc() is more like a request to the JVM, asking it to run the garbage collector as soon as it is conveniently possible. Take a look at this thread.

From personal experience, I can tell you this, try and avoid using ProgressDialog when using AsyncTask. It is painful to manage, can leak your Window object pretty easily, crash the application as soon as your devices configuration changes and pretty much give you hell trying to debug it. I've not even seen the Google apps on Android utilize ProgressDialog perfectly (uptil Gingerbread i.e. ). That's just my experience however.

Community
  • 1
  • 1
Archit
  • 887
  • 2
  • 10
  • 19
  • Thank you very much for your answer!I agree with you.To do work with ProgressDialog is painful.Do you have any good idea instead of using it? – user890973 Aug 12 '11 at 09:26
  • ProgressDialog is not all bad, its just that I've found that its inconvenient to use when working with an AsyncTask. Try using ProgressBar instead, it is a View that you can include in your layout and then subsequently change the reference to point to the one in the new layout, when handling configuration changes. – Archit Aug 12 '11 at 11:35