欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-03-08 11:54:26
...

一、消息机制的工作步骤

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进行处理。

 

 

 

相关标签: android android