Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When would Activity's instance die?

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.

like image 302
user890973 Avatar asked Nov 05 '22 16:11

user890973


1 Answers

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.

like image 182
Archit Avatar answered Nov 10 '22 17:11

Archit