android开发之内存泄露

释放双眼,带上耳机,听听看~!

内存泄露情况:

1:使用单例导致内存泄露

public class Singleton {
private static Singleton singleton=null;
private Context context;
public Singleton(Context context) {
this.context=context;
}
public static Singleton getSingleton(Context context) {
if (null == singleton) {
singleton=new Singleton(context);
}
return singleton;
}
}

原因:静态的单例使它的生命周期与应用的生命周期一样长,context一般传的是Activity或者Service等上下文,如果退出Activity,activity就没有用了,但是静态单例还会持有Activity的引用,导致无法回收,导致内存泄露。

2.WebView造成的内存泄露

原因:webview加载网页后会长期占用内存而不能释放

处理:在activity的destory()时销毁它,释放内存

@Override
protected void onDestroy() {
super.onDestroy();
rl_root.removeView(mWebView);
mWebView.clearHistory();
mWebView.removeAllViews();
}

3.动画造成的内存泄露

原因:activity在销毁的时候没有调用cancel方法,动画引用控件,控件引用activity,所以activity无法正常释放

处理:在activity的destory()时销毁它,释放内存

@Override
protected void onDestroy() {
super.onDestroy();
mAnimator.cancel();
}

4.资源未关闭导致内存泄露

处理:使用IO,Cursor后,关闭。

OutputStream out = null;
try {
out = new FileOutputStream("");
// 自己操作
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (Exception e) {
e.printStackTrace();
}
} 
    Cursor cursor = null;
try{
cursor = mContext.getContentResolver().query(uri,null,null,null,null);
if(cursor != null){
cursor.moveToFirst();
//自己处理
}
}catch(Exception e){
e.printStatckTrace();
}finally{
if(cursor != null){
cursor.close();
}
}

5. 注册广播,未关闭,操作内存泄露

处理:在activity的destory()时销毁它,释放内存

@Override
protected void onDestroy() {
super.onDestroy();
if(mReceiver != null){
this.unregisterRecevier(mReceiver);
}
}

6.非静态内部类导致内存泄露,比如handler

原因1:activity关闭了,handle的MessageQuue消队列里还有下次没有消息处理或者正在处理,导致activity无法回收。

处理:使用静态内部类加弱引用

public class ClassModelActivity extends Activity {
private Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activityclassmodel);
mHandler=new WeekHandler(this);

}

private static class WeekHandler extends Handler{
private WeakReference<ClassModelActivity > weekActivity;
public WeekHandler(ClassModelActivity activity) {
weekActivity=new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
ClassModelActivity activity=weekActivity.get();
if(activity != null){
switch (msg.what){
}
}
}
}

上面可以避免actiity内存泄露,但是messageQueue消息队列中可能还有消息消息,所以也将它清理调掉

   @Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacksAndMessages(null);
}
}

7.匿名内部类对象导致activit不能被回收

原因:直接new线程或者new AsyncTask,匿名内部类对象默认隐式持有activity对象的引用

处理:像上面一样使用静态内部类加弱引用的方式。

8. Timer和TimerTask导致内存泄露

原因:activity关闭时,Timer还在等待执行TimerTask,它持有activity对象,导致activity不能被回收

处理:activity销毁时,调用Timer和TimerTask的cancel方法。

@Override
protected void onDestroy() {
super.onDestroy();
mTime.cancel();
mTimerTask.cancel();
}

人已赞赏
Android文章

Android开发使用SwipeMenuListView

2021-2-1 8:01:10

Android文章

android开发之线程池

2021-2-1 8:54:53

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索