参考:
Android 如何有效的解决内存泄漏的问题
Java-内部类的相关知识
Android-LeakCanary检测内存泄漏
new Thread(new Runnable() {
@Override
public void run() {
try {
//模拟耗时操作
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
连续多次退出重启后发现:
将 非静态内部类 改为 静态非匿名内部类
new Thread(new MyRunnable()).start();
private static class MyRunnable implements Runnable {
@Override
public void run() {
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private final static int MESSAGECODE = 1;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.d("mmmmmmmm", "handler " + msg.what);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
handler.sendEmptyMessage(MESSAGECODE);
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendEmptyMessage(MESSAGECODE);
}
}).start();
}
连续多次退出重启后发现:
2.1、使用静态内部类
2.2、使用弱引用
2.3、在onDestroy() 里面取消异步任务。(注意:单纯的取消还是会内存泄漏)
private final static int MESSAGECODE = 1;
private static Handler handler;//静态
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建Handler
handler = new MyHandler(this);
//创建线程并且启动线程
new Thread(new MyRunnable()).start();
}
//1、避免Handler引用activity造成的内存泄漏:使用静态内部类+ 使用弱引用
private static class MyHandler extends Handler {
WeakReference weakReference;
public MyHandler(HandlerActivity activity) {
weakReference = new WeakReference(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (weakReference.get() != null) {
// update android ui
Log.d("mmmmmmmm", "handler " + msg.what);
}
}
}
//2、避免非静态Runnable内部类引用activity造成的内存泄漏
private static class MyRunnable implements Runnable {
@Override
public void run() {
handler.sendEmptyMessage(MESSAGECODE);
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendEmptyMessage(MESSAGECODE);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//3、如果参数为null的话,会将所有的Callbacks和Messages全部清除掉。
handler.removeCallbacksAndMessages(null);
}
new Timer().schedule(new TimerTask() {
@Override
public void run() {
while (true) ;
}
}, 1000); // 1秒后启动一个任务
连续多次退出重启后发现:
1、在适当的时机进行Cancel。
2、TimerTask用静态内部类
private TimerTask timerTask ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timerTask = new MyTimerTask() ;
new Timer().schedule( timerTask ,1000 ); // 1秒后启动一个任务
}
private static class MyTimerTask extends TimerTask {
@Override
public void run() {
while(true){
Log.d( "ttttttttt" , "timerTask" ) ;
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消定时任务
if ( timerTask != null ){
timerTask.cancel() ;
}
}
new AsyncTask<String,Integer,String>(){
@Override
protected String doInBackground(String... params) {
try {
Thread.sleep( 6000 );
} catch (InterruptedException e) {
}
return "ssss";
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.d( "mmmmmm activity2 " , "" + s ) ;
}
}.execute();
连续多次退出重启后发现:
1、自定义静态AsyncTask类
2、AsyncTask的周期和Activity周期应该保持一致。也就是在Activity生命周期结束时要将AsyncTask cancel掉。
private static MyTask myTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myTask = new MyTask();
myTask.execute();
}
//1、创建静态内部类
private static class MyTask extends AsyncTask {
@Override
protected Object doInBackground(Object[] params) {
try {
//模拟耗时操作
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "";
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//2、取消异步任务
if (myTask != null) {
myTask.cancel(true);
}
}