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

时间:2017-04-17 15:15:36

标签: java android loader anonymous-class asynctaskloader

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

所以使用Loaders的解决方案,其生命周期与活动的生命周期无关。

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

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

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

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

1 个答案:

答案 0 :(得分:1)

  

然而,在这样的情况下,他们定义了一个匿名的AsyncTaskLoader。在我看来,这个Loader引用了它的外部活动。

是的,它有。

  

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

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

  

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

onCreateLoader没有锁定到mLoadingIndicator引用的视图,但它只调用其中一个方法。真正重要的是mLoadingIndicator在调用onCreateLoader时引用的对象。

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

实施例

AsyncTaskLoader可以引用Activity而不会导致内存泄漏,将其包装在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();
        }
    }
}