Android 匿名 class 装载机泄漏安全吗?
Android anonymous class Loaders leak safe?
在Android开发中,我了解到AsyncTask定义为非静态嵌套class并不理想,因为当[=28=时可能会导致内存泄漏] 启动任务,在任务完成处理之前死亡。
所以使用 Loaders 的解决方案,其生命周期独立于 activity 的生命周期。
但是,在 like this 他们定义了匿名 AsyncTaskLoader 的情况下呢?在我看来,这个 Loader 有一个对其外部 activity 的引用。
(1) 这不会导致内存泄漏,开始的 activity 无法被垃圾回收吗?
此外,Loader 的 onStartLoading() 方法持有对外部 activity 成员 mLoadingIndicator 的引用。
(2) 如果仅在应用程序第一次启动时调用 onCreateLoader,此加载器是否会永远锁定第一个 activity 的 mLoadingIndicator,而忽略来自新 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?
是的,确实如此。如果这个 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
时引用的对象。
实际上装载机锁定在外部 activity。如果配置更改创建了一个新的加载指示器视图,并且仅在那时 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();
}
}
}
在Android开发中,我了解到AsyncTask定义为非静态嵌套class并不理想,因为当[=28=时可能会导致内存泄漏] 启动任务,在任务完成处理之前死亡。
所以使用 Loaders 的解决方案,其生命周期独立于 activity 的生命周期。
但是,在 like this 他们定义了匿名 AsyncTaskLoader 的情况下呢?在我看来,这个 Loader 有一个对其外部 activity 的引用。
(1) 这不会导致内存泄漏,开始的 activity 无法被垃圾回收吗?
此外,Loader 的 onStartLoading() 方法持有对外部 activity 成员 mLoadingIndicator 的引用。
(2) 如果仅在应用程序第一次启动时调用 onCreateLoader,此加载器是否会永远锁定第一个 activity 的 mLoadingIndicator,而忽略来自新 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?
是的,确实如此。如果这个 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
时引用的对象。
实际上装载机锁定在外部 activity。如果配置更改创建了一个新的加载指示器视图,并且仅在那时 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();
}
}
}