Android - This Handler class should be static or leaks might occur.

  今天学习了使用 HTTP协议,从Android客户端往Tomcat服务器端以GET发送请求,途中无意中发现自己写的Handler类被Android提示:This Handler class should be static or leaks might occur. 往google上type,发现很多网友都做了解释,也感触颇深,编译器的提示,有时真的要留意,这对自己学习也有很大的帮助.

  虽然多了几行代码,但为了实用,我就上贴自己实际点的例子,Activity:

package spt.http.get.activity;

import java.lang.ref.WeakReference;

import spt.http.get.assist.SendDataToServer;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {
	//view.
	private EditText edt_name = null;
	private EditText edt_pwd = null;
	private Button btn_ok = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
		initListener();
	}

	/**
	 * 初始化View.
	 */
	private void initView() {
		edt_name = (EditText)findViewById(R.id.edt_name);
		edt_pwd = (EditText)findViewById(R.id.edt_pwd);
		btn_ok = (Button)findViewById(R.id.btn_ok);

		//test:
		edt_name.setText("你好");
		edt_pwd.setText("abc");
	}

	/**使用静态内部类,解决‘This Handler class should be static or leaks might occur‘,以免造成内存泄露.
	 * @author Administrator
	 *
	 */
	private static class StatusHandler extends Handler {
		WeakReference<MainActivity>  iMainActivity = null;

		public StatusHandler(MainActivity mainActivity) {
			iMainActivity = new WeakReference<MainActivity>(mainActivity);
		}

		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case SendDataToServer.SEND_SUCCESS:
				//有iMainActivity.get()和iMainActivity.getClass().
				Toast.makeText(iMainActivity.get(), "发送成功", Toast.LENGTH_SHORT).show();
				break;
			case SendDataToServer.SEND_FAIL:
				Toast.makeText(iMainActivity.get(), "发送失败", Toast.LENGTH_SHORT).show();
				break;
			default:
				throw new RuntimeException("未知的发送结果!");
			}
		}
	}

	/**
	 * 处理发送是否成功的状态的Handler.
	 */
	private final  Handler handler = new StatusHandler(this);

	/**
	 * 初始化监听器.
	 */
	private void initListener() {
		btn_ok.setOnClickListener(new Button.OnClickListener() {

			@Override
			public void onClick(View v) {
				String name = edt_name.getText().toString();
				String pwd = edt_pwd.getText().toString();
				if(name.isEmpty() || pwd.isEmpty()) {
					Toast.makeText(MainActivity.this, "用户名和密码不能为空", Toast.LENGTH_SHORT).show();
					return;
				}
				new SendDataToServer(handler).send(name, pwd);
			}
		});
	}
}

将Handler声明为static,是为了解决可能出现‘内存泄露‘的问题,因为在一般情况下,通过Handler往消息队列中放入Message对象的时候,Message对象会持有对外部类的隐式引用,而是用static类,则不会对外部类有隐式引用.例如,Message对象引用主线程(UI)的视图等资源,如果不及时被处理,则他引用的对象将被一直占用,被引用的对象可能是很久以后才使用,这样一来,内存将很快被耗尽.

ref: http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1106/1922.html

时间: 2024-10-13 01:41:10

Android - This Handler class should be static or leaks might occur.的相关文章

This Handler class should be static or leaks might occur

Android中,在使用到Handler的时候,如果按如下代码编写: private Handler handler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-gene

This Handler class should be static or leaks might occur(null) 解决办法

首先解释下这句话This Handler class should be static or leaks might occur,大致意思就是说:Handler类应该定义成静态类,否则可能导致内存泄露. 具体如何解决,在国外有人提出,如下: Issue: Ensures that Handler classes do not hold on to a reference to an outer class In Android, Handler classes should be static

This Handler class should be static or leaks might occur,Handler和Context使用的注意事项!

Android中.在使用到Handler的时候,假设按例如以下代码编写: private Handler handler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-ge

The handler class should be static or leaks might occur原因及解决方法

翻译自http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html 在主线程中使用Handler对象,比如下面的代码 public class SampleActivity extends Activity { private final Handler mLeakyHandler = new Handler() { @Override public void handleMessage(Mes

Handler Class Should be Static or Leaks Occur

在使用Handler更新UI的时候,我是这样写的: public class SampleActivity extends Activity {   private final Handler mLeakyHandler = new Handler() {     @Override     public void handleMessage(Message msg) {       // TODO     }   } } 看起来很正常的,但是 Android Lint 却给出了警告: This

【Android】[转] Android Handler应设为static

android开发中,使用Lint检测时会提示这么一句话 : This Handler class should be static or leaks might occur.意为handler应用static修饰否则容易发生内存泄漏. ADT20有这么一个变化:Look for handler leaks: This check makes sure that a handler inner class does not hold an implicit reference to its ou

Android中Handler引起的内存泄露

在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.通常我们的代码会这样实现. 但是,其实上面的代码可能导致内存泄露,当你使用Android lint工具的话,会得到这样的警告 In Android, Handler classes should be static or leaks might occur, Messages enqueued on the application thread’s MessageQueue also retain their t

android之handler机制深入解析

一.android中需要另开线程处理耗时.网络的任务,但是有必须要在UI线程中修改组件.这样做是为了: ①只能在UI线程中修改组件,避免了多线程造成组件显示混乱 ②不使用加锁策略是为了提高性能,因为android中经常使用多线程. handler就是为了解决在多个线程之间的通信问题. 二.基本使用: 1 package com.dqxst.first.multithread; 2 3 import android.app.Activity; 4 import android.os.Bundle;

Android中Handler原理

Handler主要是主线程和子线程通信.一般子线程中做一些耗时操作做完之后通知主线程来修改UI. 实际上android系统在Activity启动或者状态变化等都是通过Handler机制实现的. 首先进入到ActivityThread的main方法中 public static void main(String[] args) { -- Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.