一牡彻、匿名內(nèi)部類持有外部類的引用,如常用的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);
// 異步執(zhí)行任務(wù)
new AsyncTask<Object, Void, Boolean>() {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Boolean doInBackground(Object... params) {
// do something in backfround
// 長(zhǎng)時(shí)間的耗時(shí)
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
// 長(zhǎng)時(shí)間的耗時(shí)
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();
}
};
// 異步執(zhí)行任務(wù)
mAsyncTask.execute();
}
@Override
protected void onDestroy() {
super.onDestroy();
mAsyncTask.cancel(true);
}
}
解決辦法:繼承該類,并聲明為靜態(tài)私有爷怀,因?yàn)殪o態(tài)私有類不持有外部類的引用,對(duì)于AsyncTask可以執(zhí)行cancle方法
二带欢、靜態(tài)變量持有該類的實(shí)例运授,銷毀時(shí),無(wú)法釋放該實(shí)例
以下代碼均會(huì)導(dǎo)致內(nèi)存泄漏
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);
}
}
三洪囤、單例模式導(dǎo)致的內(nèi)存泄漏
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);
}
}
原因:由于疏忽徒坡,忘了寫解綁,就會(huì)導(dǎo)致內(nèi)存泄漏
四瘤缩、屬性動(dòng)畫
屬性動(dòng)畫持有該類的一個(gè)View,若該類銷毀時(shí),屬性動(dòng)畫還在執(zhí)行伦泥,將導(dǎo)致內(nèi)存泄漏
解決辦法:調(diào)用屬性動(dòng)畫的cancel