一.handler造成内存泄漏:
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
...
}
};
非静态内部类会持有外部类的引用,handler的message的target持有handler引用,message有的是延迟处理,外部类的引用一直被持有,无法销毁,导致内存泄漏
解决方法:1,在界面销毁时调用handler.removeCallbacksAndMessages(null);移出当前界面创建的handler发送的所有message和runnable;
handler.removeCallbacks(nameRunnable);移出由这个handler发出的所有的nameRunnable;
2.使用静态内部类,把外部类的引用,以弱引用WeakReference包裹,这个方法更好
private static class MyHandler extends Handler {
private WeakReference<MainActivity> mWeakReference;
public MyHandler(MainActivity activity) {
mWeakReference = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
MainActivity mainActivity = mWeakReference.get();
switch (msg.what) {
case 1:
if (mainActivity != null) {
mainActivity.mTextView.setText(msg.obj + "");
}
break;
default:
break;
}
}
}
二.非静态内部类的静态实例
三.多线程相关的匿名内部类/非静态内部类
AsyncTask
四。未正确使用context
dialog的context必须是activity的context,如果不是必须使用activity的context的地方,我们可以考虑使用application的context
单例中,设置了context,单例的实例是静态实例,生命周期比activity长,会导致内存泄漏,如果单例里必须set一个context可以用application的context,或者用弱引用包裹
静态的Context(lint扫描)
五。静态View
使用静态view可以避免每次启动activity都去读取并渲染View,但是静态View会持有activity的引用,导致activity无法回收,解决办法是在ondestory方法中,把静态view设置为null
六。WebView
webView一般都会存在内存泄漏,解决办法:为WebView单开一个进程,使用aidl与应用的主进程进行通信,webView进程可以根据业务需求,在合适的时机销毁。
七。资源对象未关闭
比如cursor,File等,一般使用了缓存,会造成内存泄漏。在资源对象不使用时,一定要确保他们已经关闭并将他们的引用设置未null,通常在finally语句中进行关闭,防止出现异常时,资源未被释放的问题。(android lint扫描)
八。集合中对象没清理
通常把一些对象的引用加入到集合中,当不需要该对象时,如果没有把他的引用从集合中清理掉,这个集合会越来越大,如果这个集合是static的,情况会更严重。
九。bitmap对象
临时粗昂见的某个相对比较大的bitmap对象,在经过变换得到的新的bitmap对象后,应该尽快回收原始的bitmap,这样能经快释放原始bitmap所占用的空间。
十。监听器未关闭
比如eventbus需要register和unregister 的,一样要在合适的时机进行unregister。
网友评论