安卓內存泄漏場景

一、匿名內部類持有外部類的引用,如常用的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閱讀 173,242評論 25 708
  • 前幾天整理了Java面試題集合,今天再來整理下Android相關的面試題集合.如果你希望能得到最新的消息,可以關注...
    Boyko閱讀 3,656評論 8 135
  • java 接口的意義-百度 規范、擴展、回調 抽象類的意義-樂視 為其子類提供一個公共的類型封裝子類中得重復內容定...
    交流電1582閱讀 2,279評論 0 11
  • 最近過得不順,想想,大概是自己逼得太緊。 大概想想最近做的事,總有種強行扁擔當起重機用的感覺,可能是勉強了些。想想...
    嵐庸閱讀 269評論 0 2
  • 鄭老的兒子愛健身,愛參加各種體育活動,這次推遲過來頂班(姐弟六個輪流照顧老爸)是因為前不久參加足球活動而受了傷。有...
    路重波閱讀 455評論 1 0