将上下文从 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?内存泄漏?的主要内容,如果未能解决你的问题,请参考以下文章

AsyncTask 作为一个单独的类

如何将数据从 Activity 传递到已创建的 Fragment?

如何从广播接收器访问 Activity 的任何控件。不使用“静态”

将 NSManagedObject(在主上下文中创建)从后台线程传递到主线程是不是安全?

如何将位图从 Activity 传递给服务

将 View 从 setContentView 传递给非 Activity 类