android-不容易发现的内存泄漏
来源:互联网 发布:农村淘宝是做什么的? 编辑:程序博客网 时间:2024/05/16 17:09
一、Handler引起的泄漏
假如程序如下方式书写:
Handler mHandler = new Handler() { @Override public void handleMessage(android.os.Message msg) { super.handleMessage(msg); }; };
由于mHandler作为内部类,间接持有了对Activity的引用。所以当Activity即将要销毁的时候,如果mHandler消息没有及时处理完,就会导致Activity不能被释放。这样就导致了内存泄漏。
RE:可以通过Android studio中的静态检测工具来检测项目中可能存在的Handler泄漏
解决方式:1.优先使用静态的内部类 2.Handler使用弱引用
由于界面使用Handler比较多,所以通过一个自定义Handler来简化使用流程。代码如下:
/** * * 更新UI的Handler基类 避免匿名自定义Handler,而导致的内存泄露 使用时定义静态内部类,该类简化了弱引用的使用流程 * * @author ChenP * @date 2016年8月29日 上午11:04:32 */public class BaseUIHandler<T> extends Handler { /** * UI界面对象的弱引用对象 */ protected WeakReference<T> refInstance; /** * 构造函数 * * @param target * UI界面对象实例 */ protected BaseUIHandler(T target) { refInstance = new WeakReference<T>(target); } /** * 获取UI对象实例(根据弱引用对象获取,不会导致内存泄露) * * @return * @return T * @author ChenP * @date 2016年8月29日 上午11:05:22 */ protected T get() { return refInstance.get(); }}
这样在界面中使用的时候,
static class UIHandler extends BaseUIHandler<CldAndActivity> { protected UIHandler(CldAndActivity target) { super(target); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); CldAndActivity instance = get(); if (instance == null) { return; } switch (msg.what) { case 0: /** * 处理hanlder事务。----由于静态内部类不能访问外部类的方法和变量,可以通过对instance的引用来处理。 * 比如写一个dealHandler()方法,通过instance.dealHandler()来处理。 */ break; } } }
二、静态的成员变量(如果Drawable)引起泄漏
private static Drawable sBackground; @Override protected void onCreate(Bundle state) { super.onCreate(state); TextView label = new TextView(this); label.setText("Leaks are bad"); if (sBackground == null) { sBackground = getDrawable(R.drawable.large_bitmap); } label.setBackgroundDrawable(sBackground); setContentView(label); }
label.setBackgroundDrawable这个方法内部会调用 d.setCallback(this);持有对TextView的引用。但是在4.0之后才使用弱引用
public final void setCallback(Callback cb) { mCallback = new WeakReference<Callback>(cb); }
所以在4.0之前如果是静态的Drawable,持有对Activity的引用。就会导致内存泄漏
解决方式:在Activity将要onDestroy的时候,调用sBackgroundDrawable.setCallback(null)。
三、非静态内部类的静态实例容易造成内存泄漏
public class MainActivityextends Activity { static Demo sInstance = null; @Override public void onCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (sInstance == null) { sInstance= new Demo(); } } class Demo { voiddoSomething() { System.out.print("dosth."); } } }
RE:Demo作为非静态内部类,持有对Activity的应用。静态的成员变量持有对Activity的引用,就会导致Activity不能回收。
四、单例模式、外部API保存了类、上下文Context的引用
Test.getInstance().init(new TestProgressListener ());private class TestProgressListener implements ProgressListener { /** * @see com.cld.nv.frame.ICldProgressListener#onStart() */ @Override public void onStart() { } }
如果单例模式、其他API内部保存了对非静态内部类or上下文Context的引用。也会间接导致持有对Activity的引用。导致内存泄漏
参考链接:Android内存泄漏分析及调试(里面有MAT和DDMS工具的使用)
0 0
- android-不容易发现的内存泄漏
- Android Studio中不容易发现的亮点
- Android内存抖动及内存泄漏的发现、定位和解决
- 如何发现内存泄漏
- Android 的内存泄漏
- 发现 Volley 内存泄漏,求解。
- 又发现amfext的几处内存泄漏的bug
- Android 内存泄漏的原因
- android内存泄漏的原因
- android 内存泄漏的分析
- Android 内存泄漏的原因
- Android内存泄漏的情况
- Android 常见的内存泄漏
- android常见的内存泄漏
- Android 内存泄漏的排查
- [Android]常见的内存泄漏
- android内存泄漏的总结
- android 常见的内存泄漏
- Spring AOP之AspectJ的XML方式使用
- CCF-201412-3 集合竞价
- 编辑距离 (Edit distance)
- 广度优先搜索的c语言实现
- Hashmap
- android-不容易发现的内存泄漏
- 2016/9/4
- oc笔记-3
- Android SwipeRefreshLayout下拉刷新控件源码简单分析
- 新人感言
- 389. Find the Difference*
- vm安装win7系统
- Codeforces Round #334 (Div. 2) E(抽屉原理+逆元+费马小定理 )
- 小数的编程