将上下文从 Activity 传递到静态类是不是会永久保留该 Activity?内存泄漏?
Posted
技术标签:
【中文标题】将上下文从 Activity 传递到静态类是不是会永久保留该 Activity?内存泄漏?【英文标题】:Does passing a context from an Activity to a static class hold that Activity forever? Memory leak?将上下文从 Activity 传递到静态类是否会永久保留该 Activity?内存泄漏? 【发布时间】:2015-03-15 08:15:44 【问题描述】:我正在尝试设计一个 GCMHelper 类。本质上,该类是一个单例,Activity 可以请求单例来设置 GCM()。
GCMHelper.getInstance(MainActivity.this).setupGCM();
setupGCM() 方法只会查看是否需要注册 GCM(例如,应用没有 gcm,或者应用更新需要新的 gcm),如果不需要注册,则不执行任何操作。
这“没问题”,因为我的活动不需要触及 GCM id 值。一切都在单例的 setupGCM() 方法中处理。 setupGCM() 发生在后台,所以控制权回到活动。没有 UI 滞后。 GCM id 生成速度很快,但我试图解释文档中的以下错误。
公共静态最终字符串 ERROR_SERVICE_NOT_AVAILABLE
设备无法读取响应,或者来自 500/503 以后可以重试的服务器。应用程序应该使用 指数回退并重试。
所以我的 setupGCM 方法现在将继续尝试(准确地说是 5 次,每次重试之间的每次延迟之间会增加几秒钟)。但是,如果用户按下并在所述活动上调用 finish() 会发生什么。现在活动完成了,但上下文仍然用单例保存。这会导致内存泄漏吗?
即使 GCMHelper 不是单例,也会发生这种情况。它是单例的原因是,下次创建活动时,它可以查看是否已经在进行重新生成重试。
如果我将 MainActivity.this.getApplicationContext() 传递给单例所需的上下文会发生什么。这对 Activity 是否会更好,因为它可以被 GC 处理?
【问题讨论】:
是的,会导致内存泄漏。您可以将 Context 引用存储为弱引用。 将活动实例作为上下文传递——是的,它会的。传递 getApplicationContext() 实例 - 可能,但应用程序上下文通常在所有 VM 实例生命周期内保持活动状态。因此,如果应用程序上下文已死 - 您的静态类也是死类。但是如果您需要使用活动 - 您可以使用弱重放。 @VolodymyrBaydalka 传递应用程序上下文怎么样?只要 GCM 正在运行,我就可以尝试重试 gcm 的单身人士。我不想把它放在服务中,因为我也可以处理应用程序/进程被杀死并且没有完成 gcm 注册。 @Zielony 如何让我的private Context context'
成为弱引用?
如果你看到了这个? @EGHDK ***.com/questions/9809336/…
【参考方案1】:
是的,您将有内存泄漏。您应该使用应用程序上下文。 看看这篇关于上下文的好文章http://possiblemobile.com/2013/06/context/
引用:If this Context were an Activity, we would effectively hold hostage in memory all the views and other potentially large objects associated with it; creating a leak.
它甚至为您的案例提供了一个示例,使用单例:
public class CustomManager
private static CustomManager sInstance;
public static CustomManager getInstance(Context context)
if (sInstance == null)
//Always pass in the Application Context
sInstance = new CustomManager(context.getApplicationContext());
return sInstance;
private Context mContext;
private CustomManager(Context context)
mContext = context;
【讨论】:
以上是关于将上下文从 Activity 传递到静态类是不是会永久保留该 Activity?内存泄漏?的主要内容,如果未能解决你的问题,请参考以下文章
如何将数据从 Activity 传递到已创建的 Fragment?
如何从广播接收器访问 Activity 的任何控件。不使用“静态”