Android避免内存泄露
不要在Activity中使用Activity的内部类创建Runnable传入Handler或者Thread去执行.
因为匿名内部类会隐式的持有外部类的引用,如果匿名内部类对象的生命周期比外部类(eg. Activity)的生命周期更长,就会导致外部类对象没法释放.
比如在Activity中的某段代码执行
handler.postDelayed(new Runnable() {
@Override
public void run() {
}
},6000);
那么不管遇到什么情况,activity至少在60秒内不会被回收.
如果碰巧你把这代码加在了onCreate方法中,并且不停地旋转手机屏幕触发activity的重新创建,那么新的activity实例不停的产生,而应该被释放的旧activity却在60秒内一直存留在内存中.
问题就来了,如果不通过Activity的内部类创建Runnable,我们怎么访问Activity的属性和方法呢?私有的怎么办?
使用弱引用+回调函数.
//在activity类外
class MyRunnable{
WeakReference<Callback> callback;
public MyRunnable(Callback callback){
callback = new WeakReference<>(callback);
}
public void run(){
//需要回调的时候判断是否为空
if(callback.get() != null){
callback.doSomething();
}
}
}
不要在单例类持有Activity的Context
public class Singleton{
private Context context;
...
private Singleton(Context context){
this.context = context;
//this.context = context.getApplicationContext();
}
...
public static Singleton getInstance(Context context){
if(mInstance == null){
mInstance = new Singleton(context);
}
return mInstance;
}
}
如果你在调用上面的getInstance()时传入了Activity实例,那么你的Activity将会一直不能被释放,直到应用进程结束,这是非常可怕的事情.所以要写成注释的语句那样.
另外在调用这种方法的时候尽量使用ApplicationContext也可以避免你的activity被一直引用而得不到释放.