开发者

will Activity class scope field variables be accessible in AsyncTask if parent Activity finish()

Doing some testing but cannot fabricate debug environment

so maybe someone can answer this.

In my Activity i start an AsyncTask.

This AsyncTask is writing to Sqlite and it take long time.

I thought i could start the AsyncTask when user press the "Send" Button

and then hit the back button to finish() the Activity.

I know AsyncTask will keep on running even do Activity is finish() right.

The question is how do keep the fields alive?

What happen with the localArrayPeople in this code if parent finis开发者_StackOverflow社区h()?

private class AsyncTaskDoStuff extends AsyncTask<Long, Integer, Integer> 
{
    ArrayList localArrayPeople;

    @Override
    protected Integer doInBackground(Long... params) {

        this.localArrayPeople =  arrayPeople;

        // Do stuff...
    }
}

I know i can/should use a Service but the amount of data/Object's to send to the Service

is really much.

I know this is a bad ide so please for education purpose just answer the question and dont warn me


To answer yor question. Objects in java programs never just "go away", so fields don't loose references, e.g. suddenly start pointing to null. Objects are only removed by GC when nobody references them.

In your case, when Activity stops, the fields in background thread will not be affected.

The only problem could be that Android OS decides to remove your app from memory and kills all it's threads. This can happen if you have a really long running background thread and your app is inactive (= activity not showing).


Answering your original question: +1 to @PeterKnego answer.

Answering your last comment "What should i do, Make the localArrayPeople=null when im done?": No, your AsyncTask holds the reference to the Activity as every inner class holds a reference to its outer class (through the hidden this$0 field).

As stated in the article I referred in my comment ("Avoiding memory leaks"):

Avoid non-static inner classes in an activity if you don't control their life cycle, use a static inner class and make a weak reference to the activity inside.

Thus make your AsyncTaskDoStuff class a static inner one:

private static class AsyncTaskDoStuff extends AsyncTask<Long, Integer, Integer> 

If you need to use a Context object in the AsyncTask, pass the application context to AsyncTaskDoStuff constructor:

private static class AsyncTaskDoStuff extends AsyncTask<Long, Integer, Integer> {

   private final Context context;

   AsyncTaskDoStuff(Context context) {
     this.context = context;
   }

}

// in the activity:
AsyncTaskDoStuff async = new AsyncTaskDoStuff(getApplicationContext());

The same applies if you need to read some of the Activity fields, pass them through the AsyncTaskDoStuff constructor (or through its execute method).

If you need to modify Activity fields in the AsyncTask.doInBackground method do the following:

private static class AsyncTaskDoStuff extends AsyncTask<Long, Integer, Integer> {

   private final WeakReference<MyActivity> ref;

   AsyncTaskDoStuff(MyActivity activity) {
     this.ref = new WeakReference<MyActivity>(activity);
   }

   @Override
   protected Integer doInBackground(Long... params) {       
     MyActivity activity = ref.get();
     if (activity != null) {
       // access activity fields here
       activity.someField = ...
       ...
     } else {
       // activity object was already destroyed
     }
   }
}

// make sure accessed field is declared as volatile in the Activity
private volatile int someField;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜