安卓内存泄漏场景

一、匿名内部类持有外部类的引用,如常用的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
    原文作者:星林的窗
    原文地址: https://www.jianshu.com/p/7f415513e82f
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞