简体   繁体   中英

Android anonymous class Loaders leak safe?

In Android development, I've learnt that AsyncTask defined as a non-static nested class is not ideal because it may cause memory leaks when the Activity that started the task, dies before the task has finished processing.

So the solution to use Loaders , whose lifecycle is independent to that of the activity.

However, what about in a situation like this where they've defined an anonymous AsyncTaskLoader. It looks to me that this Loader has a reference to its outer activity.

(1) Does this not cause a memory leak, where the starting activity is unable to be garbage collected?

Furthermore, the Loader's onStartLoading() method holds a reference to the outer activity's member mLoadingIndicator.

(2) If onCreateLoader is only called the first time the application launches, will this loader forever latch on to that first activity's mLoadingIndicator, ignoring the view from the new activity? (For example after configuration change)

However, what about in a situation like this where they've defined an anonymous AsyncTaskLoader. It looks to me that this Loader has a reference to its outer activity.

Yes, it has.

(1) Does this not cause a memory leak, where the starting activity is unable to be garbage collected?

Yes, it does. If this Loader runs indefinitely and longer than the encompassing Activity , it may prevent the garbage collection of the context.

(2) If onCreateLoader is only called the first time the application launches, will this loader will forever latch on to that first activity's mLoadingIndicator, ignoring the view from the new activity? (For example after configuration change)

onCreateLoader doesn't latch on to the view mLoadingIndicator is referencing, but it only calls one of its methods. What really matters is the object mLoadingIndicator refers to at the time onCreateLoader is invoked.

Actually the loader latches on to the outer activity. If a configuration change created a new loading indicator view and only then onCreateLoader is invoked, the method will use the new view.

Example

An AsyncTaskLoader can refer to an Activity without causing memory leak by wrapping it in a WeakReference .

public class MyAsyncTaskLoader extends AsyncTaskLoader<String> {

    private final WeakReference<Activity> mActivity;

    public MyAsyncTaskLoader(Activity activity) {
        super(activity);
        mActivity = new WeakReference<>(activity);
    }

    public doYourThing() {
        Activity activity = mActivity.get();

        // if activity is destroyed and garbage collected,
        // it will be null
        if (activity != null) {
            activity.getYourView().setWhatever();
        }
    }
}

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