1. 静态变量引起的内存泄露
public class CommUtil {
private static CommUtil instance;
private Context context;
private CommUtil(Context context){
this.context = context;
}
public static CommUtil getInstance(Context mcontext){
if(instance == null){
instance = new CommUtil(mcontext);
}
// else{
// instance.setContext(mcontext);
// }
return instance;
}
当调用getInstance时,如果传入的context是Activity的context。只要这个单利没有被释放,那么这个
Activity也不会被释放一直到进程退出才会释放。
CommonUtils.getInstance(getActivity());
正确的写法应该是
CommonUtils.getInstance(getApplicationContext());
2. 非静态内部类引起的内存泄漏
最常见的就是我们平常总用的handler
//错误的示范:
//mHandler是匿名内部类的实例,会引用外部对象MainActivity.this。如果Handler在Activity退出的时候,它可能还活着,这时候就会一直持有Activity。
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 0:
//加载数据
break;
}
}
};
正确的handler写法
public static class MyHandler extends Handler {
//声明一个弱引用对象
WeakReference<MainActivity> mReference;
MyHandler(MainActivity activity) {
//在构造器中传入Activity,创建弱引用对象
mReference = new WeakReference<MainActivity>(activity);
}
public void handleMessage(Message msg) {
//在使用activity之前先判空处理
MainActivity main = mReference.get();
if (main == null && main .isFinishing()) {
return;
}
}
}
3. 不需要用的监听未移除会发生内存泄露
例子1:
// tv.setOnClickListener();//监听执行完回收对象
//add监听,放到集合里面
tv.getViewTreeObserver().addOnWindowFocusChangeListener(new ViewTreeObserver.OnWindowFocusChangeListener() {
@Override
public void onWindowFocusChanged(boolean b) {
//监听view的加载,view加载出来的时候,计算他的宽高等。
//计算完后,一定要移除这个监听
tv.getViewTreeObserver().removeOnWindowFocusChangeListener(this);
}
});
例子2:
SensorManager sensorManager = getSystemService(SENSOR_SERVICE);
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ALL);
sensorManager.registerListener(this,sensor,SensorManager.SENSOR_DELAY_FASTEST);
//不需要用的时候记得移除监听
sensorManager.unregisterListener(listener);
4. 资源未关闭引起的内存泄露情况
比如:BroadCastReceiver、Cursor、Bitmap、IO流、自定义属性attribute
attr.recycle()回收。
当不需要使用的时候,要记得及时释放资源。否则就会内存泄露。
5. 无限循环动画
没有在onDestroy中停止动画,否则Activity就会变成泄露对象。
比如:轮播图效果。