java – Android匿名类加载器泄漏安全吗?


Android开发中,我已经了解到
AsyncTask定义为非静态嵌套类并不理想,因为当任务启动任务时,它可能会导致内存泄漏,在任务完成处理之前就会消失.

所以使用Loaders的解决方案,其生命周期独立于活动的生命周期.

但是,在情况like this中,他们定义了一个匿名的AsyncTaskLoader.在我看来,这个Loader引用了它的外部活动.

(1)这是否会导致内存泄漏,启动活动无法进行垃圾回收?

此外,Loader的onStartLoading()方法保存对外部活动的成员mLoadingIndicator的引用.

(2)如果onCreateLoader仅在应用程序第一次启动时被调用,那么这个加载器是否会永远锁定到第一个活动的mLoadingIndicator,忽略来自新活动的视图? (例如配置更改后)

最佳答案

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?

是的,它确实.如果此Loader无限期地运行并且比包含的Activity更长,则可能会阻止上下文的垃圾收集.

(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不会锁定mLoadingIndicator引用的视图,但它只调用其中一个方法.真正重要的是mLoadingIndicator在调用onCreateLoader时引用的对象.

实际上,加载器会锁定外部活动.如果配置更改创建了新的加载指示器视图,并且只有onCreateLoader被调用,则该方法将使用新视图.

AsyncTaskLoader可以通过将其包装在WeakReference中来引用Activity而不会导致内存泄漏.

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();
        }
    }
}
点赞