Android:Handler消息机制(二)——如何使用Handler消息机制

一、消息机制的工作步骤

Handler的工作流程分为四个步骤异步通信准备、消息发送、消息循环、消息处理:

1.异步通信准备:在主线程中创建处理器对象、消息队列对象、Handler对象,Looper和MessageQueue均属于主线程,在创建MessageQueue后Looper自动进入消息循环,此时Handler自动绑定主线程的Looper、MessageQuene,并且启动子线程

2.消息入队:工作子线程通过Handler发送消息Message到消息队列MessageQueue中,该消息内容就是工作线程对UI的操作

3.消息循环:Looper会一直遍历绑定的消息队列,在消息循环过程中,若消息队列为空则线程阻塞,当队列不为空时,由Lopper逐个取出消息队列中的消息,并分发给创建该消息的Handler。

4.消息处理:处理者Handler接受Looper发送过来的消息并根据消息进行UI操作

 

二、Handler使用过程

Handler的使用方式因发送消息Message到消息队列MessageQueue的方式不同而不同,一共分为使用Handler.sendMessage()和使用Handler.post()两种方式:

方式1:使用Handler.sendMessage(),在该方式中又分为新建Handler子类和匿名Handler子类两种:

 

1.新建Handler子类

(1)自定义Handler子类,继承Handler,重写handlerMessage方法从而确定更新UI的操作,即需要执行的UI操作,根据不同线程发过来的消息执行不同的操作,可以根据Message的what属性标示不同的信息

            class mHandler extends Handler {
        		// 通过复写handlerMessage() 从而确定更新UI的操作
        		@Override
        		public void handleMessage(Message msg) {
         		...// 需执行的UI操作
        		}
    		}

(2)在主线程里创建Handler实例

private Handler mhandler = new mHandler();

(3)在多线程里通过 Message.obtain()创建所需的消息对象Message,对消息对象实例化,进行消息标示wha和消息内容obj 的存放。

Message msg = Message.obtain(); // 实例化消息对象
msg.what = ; // 消息标识
msg.obj = ; // 消息内存存放

(4)在工作线程中通过Handler发送消息到消息队列中,开起工作线程,工作线程可以使用AsyncTask、继承Thread类、实现Runnable来实现

            // 采用继承Thread类实现多线程演示
        	new Thread() {
            		@Override
            		public void run() {
                		try {
                    			Thread.sleep(3000);
                		} catch (InterruptedException e) {
                    			e.printStackTrace();
                		}
                 		Message msg = Message.obtain();
                 		msg.what = 1; // 消息标识
                 		msg.obj = "A"; // 消息内存存放
                		// 在工作线程中 通过Handler发送消息到消息队列中
                 		mHandler.sendMessage(msg);
            		}
        	}.start();

 

2.匿名Handler子类

 

(1)在主线程中 通过匿名内部类 创建Handler类对象,通过复写handlerMessage()从而确定更新UI的操作,在handleMessage里根据不同线程发送过来的消息,执行不同的UI操作

    private Handler mhandler = new  Handler(){
        @Override
        public void handleMessage(Message msg) {
            ...// 需执行的UI操作
        }
    };

(2)在工作子线程里创建所需的消息对象 Message.obtain(),对消息对象实例化,进行消息what标示和消息内容obj存放 通过Handler发送消息到消息队列中

        Message msg = Message.obtain(); // 实例化消息对象
        msg.what = ; // 消息标识
        msg.obj = ; // 消息内容存放

(3)在工作线程中通过通过Handler发送消息到消息队列中,多线程可采用AsyncTask、继承Thread类、实现Runnable,开启工作线程,同时启动了Handler

                new Thread() {
            		@Override
           		    public void run() {
                		try {
                    			Thread.sleep(3000);
                		} catch (InterruptedException e) {
                    			e.printStackTrace();
                		}
                 		Message msg = Message.obtain();
                 		msg.what = 1; // 消息标识
                 		msg.obj = "A"; // 消息内存存放
                 		// 在工作线程中 通过Handler发送消息到消息队列中
                 		mHandler.sendMessage(msg);
            		}
        	    }.start();

在主线程中通过Handler.sendMessage()调用过程

1.主线程创建时通过Looper.prepareMainLooper()和Looper.prepare(),来创建需循环器对象和消息队列对象

2.开始消息循环,通过Looper.loop()来进行循环

3. 创建Handler实例对象,通过Handler.handler()来构造实例,Handle的无参构造函数中会获取当前的Looper。不先把Looper创建好就会报错,完成指定Looper对象并绑定MessageQueue对象,并通过Handler.handeMessage()进行消息处理和回调。

4.创建消息对象,通过Message.obtain()来获取一个Message对象。

5.将消息发送到消息队列,通过Handler.sendMseeage()、Handler.enqueueMseeage()、MessageQueue.enqueueMseeage(),来获取对应的消息队列对象并将消息对象的target属性赋予handler的引用,最后发送到MessageQueue里

6.进行消息的分发,通过MessageQueue.next()、Handler.dispathMessage()、Handler.handlerMessage(),将消息出队并将消息分发到对应Handler,最终回调复写的HandlerMessage进行处理。

方式2:使用Handler.post()

 

(1)在主线程里创建Handler实例

private Handler mhandler = new mHandler();

(2)在工作线程里发送消息到消息队列,从而确定更新UI的操作,需要向Handler.post()里传入一个Runnable对象来执行UI操作

                mHandler.post(new Runnable() {
            		@Override
            		public void run() {
                		... // 需执行的UI操作 
            		}
                });

(3)开启工作线程,同时启动了Handler,多线程可采用AsyncTask、继承Thread类、实现Runnable

                    new Thread() {
            			@Override
            			public void run() {
                			try {
                    		    Thread.sleep(3000);
                			} catch (InterruptedException e) {
                    			e.printStackTrace();
                			}
                			// 通过psot()发送,需传入1个Runnable对象
                			mHandler.post(new Runnable() {
                    			@Override
                    			public void run() {
                        			// 指定操作UI内容
                        		    mTextView.setText("执行了线程1的UI操作");
                    			}
                			});
            			}
        		    }.start();

在主线程中通过Handler.post()调用过程

1.主线程创建时通过Looper.prepareMainLooper()和Looper.prepare(),来创建需循环器对象和消息队列对象

2.开始消息循环,通过Looper.loop()来进行循环

3. 创建Handler实例对象,通过Handler.handler()来构造实例,Handle的无参构造函数中会获取当前的Looper。不先把Looper创建好就会报错,完成指定Looper对象并绑定MessageQueue对象,并通过Handler.handeMessage()进行消息处理和回调

4.将消息发送到消息队列,通过Handler.post()、Runnable.run()、Handler.enqueueMseeage()、MessageQueue.enqueueMseeage(),在内部将传入的Runnable对象封装成Message对象,来获取对应的消息队列对象并将消息对象的target属性赋予handler的引用,最后发送到MessageQueue里

5.进行消息的分发,通过MessageQueue.next()、Handler.dispathMessage()、Handler.handlerMessage(),将消息出队并将消息分发到对应Handler,最终回调复写的HandlerMessage进行处理。

如果想要了解关于Handler及其相关部分的源码请看,Android:Handler消息机制(三)——Handler源码分析

猜你喜欢

转载自blog.csdn.net/ZytheMoon/article/details/105770297