android 内存泄漏的优化

来源:互联网 发布:电动牙刷推荐 知乎 编辑:程序博客网 时间:2024/05/31 18:35
1.ToastUtil.showShort(Activity.this, msg);
这个写法在Activity中传入activity的Context,容易造成内存泄漏。
这是由于 static对象是内部的static对象是比较容易造成内存泄漏的,因为toast对象是静态的,因此它的生命周期与Application同样长,因此Activity退出后,它的实例引用依然被toast持有,导致它无法被回收从而内存泄露了。所以,改为一下写法,用getApplicationContext()即可解决问题。

2.app的Activity的全局管理

      2.1传统的实现方式:之前管理Activity 的方式是在BaseActivity onCreate 方法中将Activity 实例存入工具类 或者BaseActivity 中维护的一个  List或stack中,这样能应对多数情况下的问题,但假如有Activity没有继承封装的BaseActivity,那每个Activity 就都要在onCreate方法中写添加到维护list的代码,同时当Activity销毁时,也要从list中将Activity移除,等等,逻辑可谓复杂,代码也较难维护。另外实际运用发现在MainApplication 维护一个管理Activity的静态List,并开放静态方法。比如

/** * 添加Activity到集合中*/
public void addActivity(Activity activity) {
    list.add(activity);
    int size = list.size();
    Log.i("ActivitySize",size+"");
}

/** * 从集合中移除Activity*/
public void removeActivity(Activity activity) {
    list.remove(activity);
    int size = list.size();
    Log.i("ActivitySize",size+"");
}

/** * 关闭所有的Activity*/
public static void closeActivity() {
    if (list ==null) {
        return;
    }
    for (Activity activity : list) {
        if (null != activity) {
            activity.finish();
        }
    }
    list.clear();
    /*for (Activity activity : list) {
        if (null != activity) { 
           activity.finish();       
 }   
 }*/
}
在BaseActivity里调用这些方法,容易造成内存泄漏。并且通过leakcanary的捕捉发现,大概会造成32M的内存泄漏。

    2.2终极解决方案:所幸的是,自Android 4.0(API-14)开始,Application 中多了一个方法,可以设置全局监听Activity的生命周期。这个方法就是:registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks activityLifecycleCallbacks)在传入的参数 activityLifecycleCallbacks 能得到全局所有Activity 生命周期的回调,因此 我们可以从Application中全局监听所有Activity 并对其进行管理,再也不用在Activity中处理那些扯淡的逻辑,不废话,直接上代码:
private void registerActivityListener() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override            
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                /**                 *  监听到 Activity创建事件 将该 Activity 加入list                 */               
addActivity(activity);

            }

            @Override            
public void onActivityStarted(Activity activity) {

            }

            @Override           
public void onActivityResumed(Activity activity) {

            }

            @Override            
public void onActivityPaused(Activity activity) {

            }

            @Override            
public void onActivityStopped(Activity activity) {

            }

            @Override            
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

            }

            @Override            
public void onActivityDestroyed(Activity activity) {
                if (null==list&&list.isEmpty()){
                    return;
                }
                if (list.contains(activity)){
                    /**                     *  监听到 Activity销毁事件 将该Activity 从list中移除                     */                    removeActivity(activity);
                }
            }
        });
    }
}
由此解决MainApplication全局管理Activity所造成的内存泄漏。 
原创粉丝点击