Handler使用

hander的使用

方法一

1、在New Handler的时候传入Handler.Callback对象,Handler.Callback中,并实现Handler.Callback的handleMessage方法
2、mHandler.sendMessageAtTime使用

mHandler = new Handler(new MandlerCallback());
mHandler.sendEmptyMessage(1);
private class MandlerCallback implements Handler.Callback{
        @Override
        public boolean handleMessage(Message message) {
            switch(message.what){
                case 1:
                    switchText.setText("change 1");
                    break;
            }
            return false;
        }
    }

方法二

1、无需向Hanlder的构造函数传入Handler.Callback对象,但是需要重写Handler本身的handleMessage方法

 devicehandler = new DevicegetHandler();
 devicehandler.sendEmptyMessage(MSG_DEVICE_UPDATE);

 private final class DevicegetHandler extends Handler {
        public DevicegetHandler(){
        }
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_DEVICE_UPDATE:
                    xxx
                    break;
                default:
                    break;
            }
        }
    }   

方法三 子线程

注意下面的代码存在问题,有时能运行,有时会奔溃

	TestThread mmm = new TestThread();
	mmm.start(); // 必须先启动在绑定给Looper
	mHandler = new Handler(mmm.mLooper){
	    public void handleMessage(Message msg) {
	        switch(msg.what){
	            case 1:
	                Log.d(TAG,"test hander message");
	                break;
	            default:
	                break;
	        }
	    }
	};
	private class TestThread extends Thread{
        public Looper mLooper;
        @Override
        public void run() {
            //super.run();
            Looper.prepare();
            mLooper = Looper.myLooper();
            Log.d(TAG,"TestThread run");
            Looper.loop();
        }
    }

new Handler(childThread.childLooper)的时候,run方法中的Looper对象还没初始化

修正方法1 提前执行Thread

	private TestThread mmm;
	onCreate(){
		mmm = new TestThread();
		mmm.start(); // 必须先启动在绑定给Looper
	}
	other(){
		if(mmm.mLooper != null){
			mHandler = new Handler(mmm.mLooper){
			    public void handleMessage(Message msg) {
			        switch(msg.what){
			            case 1:
			                Log.d(TAG,"test hander message");
			                 //注意这里不能做ui更新
			                break;
			            default:
			                break;
			        }
			    }
			};
		}
	}

修正方法2 --使用系统的HandlerThread

 HandlerThread handlerThread = new HandlerThread("HandlerThread");
 handlerThread.start();
 mkHandler = new Handler(handlerThread.getLooper()){
     @Override
     public void handleMessage(Message msg) {
         super.handleMessage(msg);
         Log.d(TAG,"uiThread2------"+Thread.currentThread());//子线程
     }
 };
 Log.d(TAG,"uiThread1------"+Thread.currentThread());//主线程

Handler 内存泄露

使用Handler导致内存泄露的解决方法

方法一:通过程序逻辑来进行保护。
1.在关闭Activity的时候停掉你的后台线程。线程停掉了,就相当于切断了Handler和外部连接的线,Activity自然会在合适的时候被回收。
2.如果你的Handler是被delay的Message持有了引用,那么使用相应的Handler的removeCallbacks()方法,把消息对象从消息队列移除就行了。

方法二:将Handler声明为静态类。
PS:在Java 中,非静态的内部类和匿名内部类都会隐式地持有其外部类的引用,静态的内部类不会持有外部类的引用。
静态类不持有外部类的对象,所以你的Activity可以随意被回收。由于Handler不再持有外部类对象的引用,导致程序不允许你在Handler中操作Activity中的对象了。所以你需要在Handler中增加一个对Activity的弱引用(WeakReference)。

方法一代码:

	 @Override
    protected void onDestroy() {
        super.onDestroy();
		mHandler.removeCallbacksAndMessages(null);
		mkHandler.removeCallbacksAndMessages(handlerThread);
    }

方法二代码:

扫描二维码关注公众号,回复: 11444930 查看本文章
public class NoLeakActivity extends AppCompatActivity {

    private NoLeakHandler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mHandler = new NoLeakHandler(this);

        Message message = Message.obtain();

        mHandler.sendMessageDelayed(message,10*60*1000);
    }

    private static class NoLeakHandler extends Handler{
        private WeakReference<NoLeakActivity> mActivity;

        public NoLeakHandler(NoLeakActivity activity){
            mActivity = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    }
}

注意通过该mActivity.get().去获取acitivity

 private TextView switchText;
 onCreate(){
 	mHandler = new MandlerCallback(this);
	switchText = (TextView)findViewById(R.id.switchText);
 }
 private static class MandlerCallback extends Handler{
        private WeakReference<mmmm> mActivity;
        public MandlerCallback(mmmm activity){
            this.mActivity = new WeakReference<>(activity);
        }
        @Override
        public void handleMessage(Message message) {
            switch(message.what){
                case 1:
                    mActivity.get().switchText.setText("change 2");
                    break;
            }
        }
    }

在这里插入图片描述

在这里插入图片描述

原理

源码
frameworks/base/core/java/android/os/Handler.java

猜你喜欢

转载自blog.csdn.net/LHshooter/article/details/84589226
今日推荐