当前位置: 首页 > 知识库问答 >
问题:

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

云文栋
2023-03-14

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

例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个答案

袁良弼
2023-03-14

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

阴英武
2023-03-14

不,这没什么区别。Java中的垃圾收集基于GC根的思想。如果变量是GC根或由GC根引用(包括传递),则不能对其进行垃圾收集。函数的参数是GC根,直到函数返回无法收集的参数为止。由于Activity是函数的一个参数,所以只要该函数在调用堆栈中,Activity就不可收回。使用WeakReference不会加快速度。

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

你的例子2稍微好一点,它不是完全不必要的。但是我质疑为什么需要它。一般来说,当做一个线程时,模式应该是:

run() {
   do_async_work()
   update_ui()
}

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

  //update the UI
}

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

 类似资料:
  • 问题内容: 在Java中,何时应使用静态非最终变量? 例如 显然,这里我们不是在谈论常量。 根据我的经验,我经常在使用单例时对它们进行辩护,但后来我最终需要拥有多个实例,这使我感到非常头痛和重构。 似乎很少在实践中使用它们。你怎么看? 问题答案: 统计信息收集可以使用非最终变量,例如,计算创建的实例数。另一方面,对于这种情况,您可能还是要使用etc,这时可能是最终的。另外,如果您要收集多个统计信息

  • 我即将制作我的第一个Android应用程序,我目前正在阅读有关活动和片段的信息。我打算使用Lollipop抽屉菜单功能在我的应用程序中加载不同功能的不同屏幕。像设置、关于、添加新x、浏览x等。我的导航抽屉应该为每个项目加载不同的活动单击还是加载新片段? 我所有的屏幕都有相同的风格,但内容明显不同。 如果我加载一个新活动,我是否会将导航抽屉“丢失”到一边?或者它是否始终存在,因为我希望它可以从应用程

  • 问题内容: 但是那我该如何解决呢? 我的应用程序使用几种类型的文件,我想分配一些静态属性,例如对该文件类型的描述(例如“数据文件”,另一个是“配置文件”,等等)。显然,我会将其放入静态String中,以便无需实例文件即可访问描述(对GUI fi有用)。另一方面,显然所有文件类型都应具有一些通用方法,例如,显然我想从通用超类继承。 在超类中当然是抽象的。 尝试使用超类和接口的组合,但是存在类似的问题

  • 我想知道人们在bigquery上构建和管理ETL作业时发现了哪些最佳实践/工具。 目前,我有很多sql模板(可怕的参数化的lob,日期等使用sed类型字符串替换成一个tmp.sql文件,然后运行),我使用命令行工具来运行它们的序列并将输出发送到表。它工作正常,但有点笨拙。我仍然不明白为什么我不能在bigQuery上运行存储过程类型参数化脚本。甚至是某种图形用户界面来构建和管理管道。 我喜欢bigq

  • 本文向大家介绍ThreadPoolExecutor 创建方法最佳实践?相关面试题,主要包含被问及ThreadPoolExecutor 创建方法最佳实践?时的应答技巧和注意事项,需要的朋友参考一下 在《阿里巴巴 Java 开发手册》“并发处理”这一章节,明确指出线程资源必须通过线程池提供,不允许在应用中自行显示创建线程。 为什么呢? 使用线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源开

  • 好的,所以我找不到关于这个主题的任何有用的材料,我找到的一大块文章中有一个方法是用@HystrixCommand注释的,并且定义了一个回退方法。 我找到的另一个解决方案是使用@DefaultProperties(defaultFallback=“fallbackMethod”),但问题是这些方法需要具有兼容的返回类型。 不幸的是,在我的服务中,我有许多具有完全不同签名的方法,我还需要掌握可抛出的方