弱いリファレンスおよび静的内部クラスによるメモリ漏洩の問題の低減


我々は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();

				}

			}

		}

	}

}