通过弱引用及静态内部类减少内存泄漏问题
我们在开发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(); } } } } }