我们先看一个简单的例子
MainActivity.java
package com.studio.countdowntime;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
public static final int COUNTDOWN_TIME_CODE = 10001;
public static final int DELAY_MILLIS = 1000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//得到控件
final TextView countdownTimeTextView = (TextView) findViewById(R.id.countdownTimeTextView);
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg != null && msg.what == COUNTDOWN_TIME_CODE){
countdownTimeTextView.setText(String.valueOf(9));
}
}
};
Message message = Message.obtain();
message.what = COUNTDOWN_TIME_CODE;
handler.sendMessageDelayed(message, DELAY_MILLIS);
}
}
我们这么写程序运行结果是没有问题的,但是我们会发现handler上有一个警告:
大意是这个handler应该是静态的,否则会造成内存泄露。原因是我们看到if语句中的countdownTimeTextView是一个在Mainactivity里面定义的控件对象,假如if语句还没有执行到,而当前的Activity已经被销毁了,这个时候发的消息还有可能过来,过来之后还持有这个控件的引用,还需要处理if语句。这个时候handler还持有Activity,但是该Acitivity垃圾回收的时候就无法回收,这个时候就有可能造成内存的泄露
Java 中强应用和弱引用
package com.studio.countdowntime;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import java.lang.ref.WeakReference;
public class MainActivity extends AppCompatActivity {
/**
* 倒计时标记handler code
*/
public static final int COUNTDOWN_TIME_CODE = 10001;
/**
* 倒计时间隔
*/
public static final int DELAY_MILLIS = 1000;
/**
* 倒计时最大值
*/
public static final int MAX_COUNT = 10;
private TextView countdownTimeTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//得到控件
countdownTimeTextView = (TextView) findViewById(R.id.countdownTimeTextView);
//创建了一个handler
CountdownTileHandler handler = new CountdownTileHandler(this);
//新建了一个message
Message message = Message.obtain();
message.what = COUNTDOWN_TIME_CODE;
message.arg1 = MAX_COUNT;
//第一次发送message
handler.sendMessageDelayed(message, DELAY_MILLIS);
}
public static class CountdownTileHandler extends Handler {
public static final int MIN_COUNT = 0;
final WeakReference<MainActivity> mWeakReference;
CountdownTileHandler(MainActivity activity) {
mWeakReference = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
MainActivity mainActivity = mWeakReference.get();
switch (msg.what) {
case COUNTDOWN_TIME_CODE:
int value = msg.arg1;
mainActivity.countdownTimeTextView.setText(String.valueOf(value--));
//循环发消息控制
if (value >= MIN_COUNT) {
Message message = Message.obtain();
message.what = COUNTDOWN_TIME_CODE;
message.arg1 = value;
sendMessageDelayed(message, DELAY_MILLIS);
}
break;
}
}
}
}