一、匿名内部类持有外部类的引用,如常用的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