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
.
I thought i could start the AsyncTask
when user press the "Send" Button
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
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;
精彩评论