Android单例内存泄漏解决方案

一、背景

项目中经常会出现一个ActivityManager来管理所有的activity,当Activity生命周期结束时,作为单例的ActivityManager还持有Activity的这个实例,因此引发了内存泄漏。

二、解决方案

这个时候,只能想到谷歌推荐使用的弱引用WeakReference,也比较简单,修改好的单例写法如下:

package com.chaoxing.email.utils;
 
import android.app.Activity;
import android.content.Context;
 
import java.lang.ref.WeakReference;
import java.util.HashMap;
 
 
public class ActivityManager {
    
    
    private HashMap<String, WeakReference<Activity>> activities = new HashMap<>();
    private static ActivityManager activityManager;
 
    private ActivityManager() {
    
    
    }
 
 
    public static ActivityManager getInstance() {
    
    
        if (null == activityManager) {
    
    
            activityManager = new ActivityManager();
        }
        return activityManager;
    }
 
    public void addActivity(Activity activity) {
    
    
        if (null != activity) {
    
    
            activities.put(activity.getClass().getSimpleName(), new WeakReference<>(activity));
        }
    }
 
    public void exitApp() {
    
    
 
        for (String key : activities.keySet()) {
    
    
            WeakReference<Activity> weakReference = activities.get(key);
            if (null != weakReference && weakReference.get() != null) {
    
    
                weakReference.get().finish();
            }
        }
    }
 
    public static boolean isContextInvalid(final Context context) {
    
    
        return context == null || ((Activity) context).isFinishing();
    }
}

修改后运行了程序,关闭Activity,等待了10秒(LeakCannary的检测机制),没有发现泄漏,反复几次,并没有发现内存泄漏。

三、小彩蛋

上面是项目中遇到的问题,对于大家平时开发过程中,经常会有泄漏的问题,而且在编码的过程中也是可以避免的,因为大谷歌开发的IDE神器 Android Studio(现在最新版是3.0 Beta4,我现在就是这个版本)有检测内存泄漏的提示.

比如下图注意看右边的黄色警告提示:
在这里插入图片描述
然后IDE给出的提示(或者把鼠标直接放到该MailOptionHandler的类上)会出现以下的建议:

This Handler class should be static or leaks might occur (com.chaoxing.email.fragment.EmailPullFragment.MailOptionHandler) less… (Ctrl+F1)
Since this Handler is declared as an inner class, it may prevent the outer class from being garbage collected. If the Handler is using a Looper or MessageQueue for a thread other than the main thread, then there is no issue. If the Handler is using the Looper or MessageQueue of the main thread, you need to fix your Handler declaration, as follows: Declare the Handler as a static class; In the outer class, instantiate a WeakReference to the outer class and pass this object to your Handler when you instantiate the Handler; Make all references to members of the outer class using the WeakReference object.

意思是该地方可能会存在泄漏,建议使用static 和 WeakReference 来进行修改.

按照该条建议,将该类修改为静态“static”,并使用了WeakReference 弱引用的持有该Fragment的对象实例,解决该泄漏.

猜你喜欢

转载自blog.csdn.net/weixin_42600398/article/details/124626501