最佳实践:静态方法中对 activity 的弱引用
Best practice: weak reference to activity in static method
我需要在多个静态方法中引用 activity。我很想知道避免内存泄漏的最佳做法。让我们使用示例:
示例 1:
static void hideKeyboard(Activity activity) {
WeakReference<Activity> activityReference = new WeakReference<>(activity);
// ... Call activityReference.get() when needed, check if null...
}
示例 2:
static void hideKeyboard(WeakReference<Activity> activityReference) {
// ... Call activityReference.get() when needed, check if null...
}
所以三个问题:
- 示例 1 或示例 2 有什么不同吗?
- 我还没有看到在
Thread
或 AsyncTask
的子类之外以这种方式调用方法。有什么理由吗?我错过了什么吗?
- 如果在这些方法之一的
Thread
或 AsyncTask
中使用弱引用,内存是否仍然会泄漏?
绝对没有理由在传递给方法的参数中使用 WeakReference
,除非此参数被 存储。如果参数只在方法中使用,直接传入Activity
引用即可。
不,这没有什么不同。 Java 中的垃圾收集基于 GC 根的思想。如果变量是 GC 根或被 GC 根引用(包括传递),则它不能被垃圾收集。函数的参数是一个 GC root- 直到函数 returns none 可以收集其参数。由于 Activity 是您函数的参数,因此只要该函数在调用堆栈中,它就无法收集。使用 WeakReference 不会加快速度。
Threads 和 AsyncTasks(实际上只是 Thread 的包装器)略有不同。每个 运行 线程也是一个 GC 根。但是线程可以有很长的生命周期,并且存在于对象的生命周期之外。在这里,使用 WeakReference 可能会有所帮助,因为没有其他原因需要保留它(例如示例中的参数)。
您的示例 2 稍好一些,显然没有必要。但我质疑为什么需要它。一般来说,在做线程时,模式应该是:
run() {
do_async_work()
update_ui()
}
update_ui() {
Activity activity = weakReference.get()
if(activity == null) {
return
}
//update the UI
}
这样做可以避免很多问题,比如需要检查十几次弱引用。
我需要在多个静态方法中引用 activity。我很想知道避免内存泄漏的最佳做法。让我们使用示例:
示例 1:
static void hideKeyboard(Activity activity) {
WeakReference<Activity> activityReference = new WeakReference<>(activity);
// ... Call activityReference.get() when needed, check if null...
}
示例 2:
static void hideKeyboard(WeakReference<Activity> activityReference) {
// ... Call activityReference.get() when needed, check if null...
}
所以三个问题:
- 示例 1 或示例 2 有什么不同吗?
- 我还没有看到在
Thread
或AsyncTask
的子类之外以这种方式调用方法。有什么理由吗?我错过了什么吗? - 如果在这些方法之一的
Thread
或AsyncTask
中使用弱引用,内存是否仍然会泄漏?
绝对没有理由在传递给方法的参数中使用 WeakReference
,除非此参数被 存储。如果参数只在方法中使用,直接传入Activity
引用即可。
不,这没有什么不同。 Java 中的垃圾收集基于 GC 根的思想。如果变量是 GC 根或被 GC 根引用(包括传递),则它不能被垃圾收集。函数的参数是一个 GC root- 直到函数 returns none 可以收集其参数。由于 Activity 是您函数的参数,因此只要该函数在调用堆栈中,它就无法收集。使用 WeakReference 不会加快速度。
Threads 和 AsyncTasks(实际上只是 Thread 的包装器)略有不同。每个 运行 线程也是一个 GC 根。但是线程可以有很长的生命周期,并且存在于对象的生命周期之外。在这里,使用 WeakReference 可能会有所帮助,因为没有其他原因需要保留它(例如示例中的参数)。
您的示例 2 稍好一些,显然没有必要。但我质疑为什么需要它。一般来说,在做线程时,模式应该是:
run() {
do_async_work()
update_ui()
}
update_ui() {
Activity activity = weakReference.get()
if(activity == null) {
return
}
//update the UI
}
这样做可以避免很多问题,比如需要检查十几次弱引用。