防止内存泄漏注意事项

2019-10-18  本文已影响0人  夜行者_姚

1、Handler使用

privateMyHandler mHandler =newMyHandler(this);

//自定义静态内部类继承自Handler

privatestaticclassMyHandlerextendsHandler{

        privateWeakReference reference;

     //在构造函数中使用弱引用来引用context对象

       publicMyHandler(Context context){

        reference =newWeakReference<>(context);

  }

@Override

publicvoidhandleMessage(Message msg){

            MainActivity activity = (MainActivity) reference.get();

            if(activity !=null){

            activity.mTextView.setText("");

          }

   }

}

@Override

protectedvoidonDestroy(){

    super.onDestroy();

    //移除队列中所有的Runable和消息

    //这里也可以使用mHandler.removeMessage和mHandler.removeCallBacks来移除指定的Message和Runable

    mHandler.removeCallbacksAndMessages(null);

  }

2、单例的使用,如果单例中需要传入context或者activity

单例设计模式的静态特性会使他的生命周期和应用程序的生命周期一样长,这就说明了如果一个对象不在使用了,而这时单例对象还在持有该对象的引用,这时GC就会无法回收该对象,造成了内存泄露的情况。

1、如果我们传入的Context是Application的Context的话,就没有任何问题,因为Application的Context生命周期和应用程序生命周期一样长。

2、如果我们传入的Context是Activity的Context的话,这时如果我们因为需求销毁了该Activity的话,Context也会随着Activity被销毁,但是单例还在持有对该类对象的引用,这时就会造成内存泄漏。

public class AppManager { 

     private static AppManager instance;

     private Context context;

     private AppManager(Context context) { 

     this.context = context.getApplicationContext(); 

 } 

 public static AppManager getInstance(Context context) {

     if (instance != null) {

     instance = new AppManager(context);

    } 

     return instance; 

 } 

3、静态内部类的使用

这样就在Activity中创建了非静态内部类,非静态内部类默认持有Activity类的引用,但是他的生命周期还是和应用程序一样长,所以当Activity销毁时,静态内部类的对象引用不会被GC回收,就会造成了内存溢出,解决办法:

1、将内部类改为静态内部类。

2、将这个内部类封装成一个单例,Context使用Application的Context

4、资源未关闭,以及使用一些图片过大。

对于使用了BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等资源的使用,应该在Activity销毁时及时关闭或者注销,否则这些资源将不会被回收,造成内存泄漏。

5线程问题

线程造成:匿名内部类Runnalbe和AsyncTask对象执行异步任务,对当前Activity隐式引用。当Activity销毁之前,任务还没有执行完,将导致Activity的内存和资源不能及时回收;

 资源未关闭造成的内存泄露:对于使用了BroadcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等资源的使用,应该在Activity销毁时及时关闭或者注销,否则这些资源将不会被回收,造成内存泄露;

 6webview问题

就是在销毁webview前一定要onDetachedFromWindow,我们先将webview从它的父view中移除再调用destroy方法,代码如下:

@Override

protected void onDestroy() {

  super.onDestroy();

  if (mWebView != null) {

      ViewParent parent = mWebView.getParent();

      if (parent != null) {

        ((ViewGroup) parent).removeView(mWebView);

      }

      mWebView.removeAllViews();

      mWebView.destroy();

      mWebView = null;

  }

}

上一篇 下一篇

猜你喜欢

热点阅读