Activity、Fragment和Conetext
1、使用mvvm框架:
1)不传Context到Viewmodel。如果Application代替不了,实在需要Activity,则通过Livedata交到Activity中处理相关逻辑。
2)在Viewmodel的onCleared()方法中,清除Viewmodel和Model中的数据;
可借鉴:
【Android】完善的mvvm架构封装demo(可项目中使用) - 简书
2、使用mvp框架:
1)Presenter持有View使用弱引用,Context获取使用View,不要再传入Context;
2)Presenter调用Model如果使用匿名内部类作为参数则可借鉴第5点,或者使用接口传递给Model代替匿名内部类,Model中弱引用持有回调接口,在回调时做判空;
3)在界面销毁时,Presenter和Model需要把数据清空;
可借鉴:
【Android】完善的mvp架构封装demo(可项目中使用) - 简书
3、内部类如果生命周期比Activity/Fragment长,则改为静态内部类,需要调用Activity/Fragment方法则将Activity/Fragment传入并使用弱引用保存为成员变量。handler也是如此处理。
4、实在需要把Activity传入生命周期比Activity长的类,应该使用弱引用,使用时判断是否为空。
5、Activity/Fragment中使用单例等生命周期比Activity/Fragment长的类,在方法调用时注意匿名内部类作为参数,需要清楚此匿名内部类的生命周期是否比Activity/Fragment长,如果是则需要再封装一层,将最外层的匿名内部类参数转化成弱引用。常见有Handler、线程、rxjava。
示例:
findViewById(R.id.text).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Log.i("MainActivity", "post run: ");
}
}, 8000);
}
});
Handler生命周期比Activity长,参数中有匿名内部类,会造成内存泄漏;
我们多封装一层,新增个接口加个弱引用,再传入匿名内部类;
public class HandleTest {
private WeakReference<RunCallBack> runCallBackWeakReference;
void post(RunCallBack runCallBack) {
//传入匿名内部类之前转为弱引用,否则一旦传入匿名内部类,则被嵌套持有
runCallBackWeakReference = new WeakReference<>(runCallBack);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (runCallBackWeakReference != null) {
RunCallBack runCallBack1 = runCallBackWeakReference.get();
if (runCallBack1 != null) {
runCallBack1.run();
}
}
}
}, 8000);
}
public interface RunCallBack {
void run();
}
}
调用时
HandleTest handleTest = new HandleTest();
handleTest.post(new HandleTest.RunCallBack() {
@Override
public void run() {
Log.i("MainActivity", "post1 run: ");
}
});
6、耗时操作可以使用rxjava,注意添加AutoDispose库的使用。
关于静态变量
1、使用完成后,必须置空,对于非数据类型的对象,如Activity、View等,最好不要保存;
2、静态变量使用弱引用是无效的,因为系统不会主动回收静态变量;
3、特别要注意单例,要有个统一回收的方法;
其他
1、在使用一些资源,如数据库连接、游标 Cursor、文件输入/输出流、BraodcastReceiver、ContentObserver、Bitmap等时,如果在使用完毕后未显式关闭这些资源,会导致资源泄漏和内存泄漏。应该使用try finally,在finally中关闭资源;
2、生命周期长的类缓存生命周期短的数据时,应使用弱引用,常见是集合和Map;
3、使用享元设计模式,避免构造重复资源,比如ListView的convertView;
4、EventBus,RxJava等一些第三开源框架的使用,在Activity销毁之前要进行解除订阅;