安卓内存泄漏场景

一、匿名内部类持有外部类的引用,如常用的Thread、Handler和AsyncTask
如下:

public class SyncTaskDemoActivity extends Activity {  
    private int today = 0;  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  

        // 异步执行任务  
        new AsyncTask<Object, Void, Boolean>() {  
            @Override  
            protected void onPreExecute() {  
                super.onPreExecute();  
            }  
  
            @Override  
            protected Boolean doInBackground(Object... params) {  
                // do something in backfround  
                // 长时间的耗时  
                while (true) {  
                    today++;  
                    if (today > 100000)  
                        break;  
                }  
                return true;  
            }  
  
            @Override  
            protected void onPostExecute(Boolean result) {  
                super.onPostExecute(result);  
                if (result) {  
                    // success do something  
                } else {  
                    // error  
                }  
            }  
        }.execute();  
    }  
} ```
修改后:

public class SyncTaskDemoActivity extends Activity {
private int today = 0;
private AsyncTask mAsyncTask;

@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.activity_main);  

    mAsyncTask = new AsyncTask<Object, Void, Boolean>() {  
        @Override  
        protected void onPreExecute() {  
            super.onPreExecute();  
        }  

        @Override  
        protected Boolean doInBackground(Object... params) {  
            // do something in backfround  
            // 长时间的耗时  
            while (true) {  
                if (cancel(true))  
                    break;  
                today++;  
                if (today > 100000)  
                    break;  
            }  
            return true;  
        }  

        @Override  
        protected void onPostExecute(Boolean result) {  
            super.onPostExecute(result);  
            if (result) {  
                // success do something  
            } else {  
                // error  
            }  
        }  

        @Override  
        protected void onCancelled() {  
            super.onCancelled();  
        }  
    };  
    // 异步执行任务  
    mAsyncTask.execute();  
}  

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

}


解决办法:继承该类,并声明为静态私有,因为静态私有类不持有外部类的引用,对于AsyncTask可以执行cancle方法

二、静态变量持有该类的实例,销毁时,无法释放该实例
以下代码均会导致内存泄漏

public class MainActivity extends Activity{
private static Context sContext;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sContext = this;
}
}

public class MainActivity extends Activity{
private static View view;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
view = new View(this);
}
}

三、单例模式导致的内存泄漏

public class TestManager{
private List<OnDataArrivedListener> listeners = new ArrayList<>();
private static class SingletonHolder{
public static final TestManager instance = new TestManager();
}

private TestManager(){
    
}

public static TestManager getInstance(){
    return SingletonHolder.instance;
}

public synchronized void registerListener(OnDataArrivedListener listener){
    if (!listeners.equals(listener))
        listeners.add(listener);
}

public synchronized  void unregisterListener(OnDataArrivedListener listener){
    if (listeners.equals(listener))
        listeners.remove(listener);
}

public interface OnDataArrivedListener{
    public void onDataArrived(Object data);
}

}

原因:由于疏忽,忘了写解绑,就会导致内存泄漏

四、属性动画
属性动画持有该类的一个View,若该类销毁时,属性动画还在执行,将导致内存泄漏
解决办法:调用属性动画的cancel
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,143评论 25 709
  • 前几天整理了Java面试题集合,今天再来整理下Android相关的面试题集合.如果你希望能得到最新的消息,可以关注...
    Boyko阅读 3,717评论 8 135
  • java 接口的意义-百度 规范、扩展、回调 抽象类的意义-乐视 为其子类提供一个公共的类型封装子类中得重复内容定...
    交流电1582阅读 2,326评论 0 11
  • 最近过得不顺,想想,大概是自己逼得太紧。 大概想想最近做的事,总有种强行扁担当起重机用的感觉,可能是勉强了些。想想...
    岚庸阅读 274评论 0 2
  • 郑老的儿子爱健身,爱参加各种体育活动,这次推迟过来顶班(姐弟六个轮流照顾老爸)是因为前不久参加足球活动而受了伤。有...
    路重波阅读 465评论 1 0