最佳实践:静态方法中对活动的弱引用

发布于 2025-01-20 14:12:27 字数 734 浏览 1 评论 0原文

我需要在几个静态方法中引用一个活动。我很想知道避免内存泄漏的最佳实践。让我们举个例子:

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

I need to reference an activity in several static methods. I'm curious to know the best practices to avoid memory leaks. Let's use examples:

Example 1:

static void hideKeyboard(Activity activity) {
   WeakReference<Activity> activityReference = new WeakReference<>(activity);
   // ... Call activityReference.get() when needed, check if null...
}

Example 2:

static void hideKeyboard(WeakReference<Activity> activityReference) {
   // ... Call activityReference.get() when needed, check if null...
}

So three questions:

  1. Do example 1 or 2 make any difference?
  2. I haven't seen methods being called this way much outside of subclasses of Thread or AsyncTask. Any reason why? Am I missing something?
  3. If the weak reference is used in a Thread or AsyncTask inside one of those methods, could memory still leak?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

表情可笑 2025-01-27 14:12:27

不,这没有区别。 Java中的垃圾收集工作了GC根的想法。如果变量是GC根或GC根引用(包括过渡性),则不能收集垃圾。函数的参数是GC root-直到函数返回其参数都无法收集。由于活动是您函数的参数,因此只要该函数在呼叫堆栈中,它就会是无法填充的。使用虚弱不会加快它的速度。

线程和异步箱(实际上只是围绕线程的包装器)略有不同。每个运行线程也是GC根。但是线程可以长寿,并且存在于对象的生命周期之外。在这里,使用弱率确实可能会有所帮助,因为没有其他原因需要保留(例如样本中的参数)。

您的示例2更好,这不是公然不必要的。但是我质疑为什么需要它。通常,在执行线程时,模式应该是:

run() {
   do_async_work()
   update_ui()
}

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

  //update the UI
}

这样做将阻止许多问题,例如需要检查弱参考。

No, it doesn't make a difference. Garbage collection in Java works on the idea of GC roots. If a variable is a GC root or references by a GC root (including transitively) it cannot be garbage collected. Parameters to a function are a GC root- until the function returns none of its parameters can be collected. Since Activity is a parameter to your function, it will be uncollectable as long as that function is in the call stack. Using a WeakReference won't speed it up.

Threads and AsyncTasks (which are just wrappers around Thread really) are slightly different. Every running thread is also a GC root. But threads can have a long lifetime and exist beyond the lifecycle of the object. Here, using a WeakReference does possibly help because there isn't another reason it needs to be kept around (like the parameter in your sample).

Your example 2 is a bit better, it isn't blatantly unnecessary. But I question why its needed. In general when doing a Thread the pattern should be:

run() {
   do_async_work()
   update_ui()
}

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

  //update the UI
}

Doing it like this will prevent a lot of problems like needing to check the weak reference a dozen times.

红衣飘飘貌似仙 2025-01-27 14:12:27

绝对没有理由在传递给方法的参数中使用fealReference,除非该参数已存储。如果仅在方法中使用该参数,则只需传递活动参考即可。

There is absolutely no reason to use WeakReference in a parameter passed to a method, unless this parameter is being stored. If the parameter is only used in the method, you can just pass in the Activity reference.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文