我们在开发app时,经常会使用静态内部类。在使用Handler类时,若不定义一个静态Handler子类,在使用是会提示This Handler class should be static or leaks might occur。就是说Handler类需要定义为静态类,否则可能会出现内存泄漏。
一般的解决办法如下:
1、定义一个静态内部类,继承自Handler
2、在静态内部类声明一个弱引用
下面通过一个下载图片功能的Activity例子来说明:
/**
* 解决This Handler class should be static or leaks might occur 问题
*
*/
public class HandlerLeakResolverActivity extends Activity {
private static final String uri = "http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg";
private ImageView imageView;
private Handler handler = new MyHandler(this);
private ProgressDialog dialog;
private static final Integer FINISHED = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image_load_layout);
imageView = (ImageView) findViewById(R.id.imageView1);
Button downloadImg = (Button) findViewById(R.id.btn_downloadImg);
dialog = new ProgressDialog(this);
dialog.setMessage("正在下载,请稍后...");
dialog.setCancelable(false);
downloadImg.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
imageView.setImageBitmap(null);
// 启动新activity下载,可以显示图片
new DownloadThread().start();
dialog.show();
}
});
}
/**
* 自定义线程类,用于异步下载图片
* @author Chase
*
*/
private class DownloadThread extends Thread {
@Override
public void run() {
Bitmap bitmap=null;
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(uri);
HttpResponse httpResponse = null;
try {
httpResponse = httpClient.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
byte[] data = EntityUtils.toByteArray(httpResponse
.getEntity());
bitmap=BitmapFactory.decodeByteArray(data, 0, data.length);
Message msg = Message.obtain();
msg.obj = bitmap;
msg.what = FINISHED;
handler.sendMessage(msg);
}
} catch (Exception e) {
Log.e(this.getClass().getName(),"图片下载出错!",e);
}
}
}
/**
* 定义一个Handler静态内部类
* @author Chase
*
*/
static class MyHandler extends Handler{
// Activity的弱引用
WeakReference<HandlerLeakResolverActivity> reference;
public MyHandler(HandlerLeakResolverActivity activity) {
reference = new WeakReference<HandlerLeakResolverActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
HandlerLeakResolverActivity activity = reference.get();
if(activity != null){
if(msg.what == FINISHED){
Bitmap bmp = (Bitmap)msg.obj;
activity.imageView.setImageBitmap(bmp);
activity.dialog.dismiss();
}
}
}
}
}