最佳实践:静态方法中对 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. 示例 1 或示例 2 有什么不同吗?
  2. 我还没有看到在 ThreadAsyncTask 的子类之外以这种方式调用方法。有什么理由吗?我错过了什么吗?
  3. 如果在这些方法之一的 ThreadAsyncTask 中使用弱引用,内存是否仍然会泄漏?

绝对没有理由在传递给方法的参数中使用 WeakReference,除非此参数被 存储。如果参数只在方法中使用,直接传入Activity引用即可。

不,这没有什么不同。 Java 中的垃圾收集基于 GC 根的思想。如果变量是 GC 根或被 GC 根引用(包括传递),则它不能被垃圾收集。函数的参数是一个 GC root- 直到函数 returns none 可以收集其参数。由于 Activity 是您函数的参数,因此只要该函数在调用堆栈中,它就无法收集。使用 Wea​​kReference 不会加快速度。

Threads 和 AsyncTasks(实际上只是 Thread 的包装器)略有不同。每个 运行 线程也是一个 GC 根。但是线程可以有很长的生命周期,并且存在于对象的生命周期之外。在这里,使用 Wea​​kReference 可能会有所帮助,因为没有其他原因需要保留它(例如示例中的参数)。

您的示例 2 稍好一些,显然没有必要。但我质疑为什么需要它。一般来说,在做线程时,模式应该是:

run() {
   do_async_work()
   update_ui()
}

update_ui() {
  Activity activity = weakReference.get()
  if(activity == null) {
     return
  }

  //update the UI
}

这样做可以避免很多问题,比如需要检查十几次弱引用。