Handle初解,看完你就懂了handle

您所在的位置:网站首页 ui设计到底是干嘛的啊 Handle初解,看完你就懂了handle

Handle初解,看完你就懂了handle

2024-06-19 09:50| 来源: 网络整理| 查看: 265

文章目录 前言一、Handle是什么?二、Handle有啥用呢?1.传递消息到ui线程2.代码示例3注意点 最后

前言

提示:看完本篇,你可以了解到Handle的相关知识与常见的误区提醒

一、Handle是什么?

我们查看一下谷歌官方对其的定义: A Handler allows you to send and process {@link Message} and Runnable objects associated with a thread’s {@link MessageQueue}. Each Handler instance is associated with a single thread and that thread’s message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it – from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.

Handler它可以通过消息队列发送消息或者runable对象,也可以处理消息或者runable对象。每一个handler实例,都持有一个线程以及此线程的消息队列。 那么handle相当于什么呢?其实就相当于我们现实世界的搬运工,可以发送消息,也可以处理消息。

二、Handle有啥用呢? 1.传递消息到ui线程

在我们安卓开发的时候,我们都知道ui线程是不可以进行耗时操作的,如果在这里进行的话,就会导致ANR,因此开辟一个子线程,在子线程中去处理相关的耗时任务,这是必然的结果。那么处理完的结果需要改变ui,即我们的控件显示的时候怎么办呢?在子线程中处理完直接改变ui是安卓中不允许的行为,因为ui线程不是线程安全的,那么我们有必要需要一个工具将子线程处理的结果带回去给ui线程去显示,而handle正是完成了这个任务。

2.代码示例 主线程定义一个handle(mHandle),构造方法里面new一个callback,复写handleMessage方法,这 就表明当有信息来的时候,由handleMessage方法去执行 mHandler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(@NonNull Message msg) { //处理消息 if(msg.what == 1) { Log.d("hanldeTest","object is -- > " + msg.obj); } return false; } }); 子线程中,假设处理完了一些耗时操作,比如读写数据库,随后即可执行一下代码 Message message = mHandler.obtainMessage(); message.what = 1; message.obj = "我是新消息!"; mHandler.sendMessage(message);

这样子一个发送,一个接受,就完成了就基本的handle使用,值得注意的是,上诉方法已经过期了 在这里插入图片描述 下面是最新的使用方法:

boolean test=new Handler(getMainLooper()).post(new Runnable() { @Override public void run() { //更新ui处理,在耗时任务完成后 } });

这里细心观察的小伙伴就会发现,参数里面有一个getMainLooper(),字面意思就是获得主looper对吧,那么looper是个啥?拿了有啥用?我们先以过期的方法去解释更方便 handle源码:

public Handler(@Nullable Callback callback, boolean async) { if (FIND_POTENTIAL_LEAKS) { final Class klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { Log.w(TAG, "The following Handler class should be static or leaks might occur: " + klass.getCanonicalName()); } } mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread " + Thread.currentThread() + " that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; }

这里有个值得的两个对象,mLooper,mQueue。当系统创建一个ActivityThread的时候,也创建了一个Looper,在looper里面有一个消息队列(其实是单链表结构的东西),Looper负责不断循环保持我们的程序不会结束,queue则负责接受消息,然后有handle去处理。我们一个线程只有一个looper,负责当前线程的不中断,但是handle可以有多个,所有的handle都依附于某个消息队列(没有队列你要搬运工干嘛对吧),而队列由looper创建,这也相当于handle间接依赖于looper了嘛~(看源码mQueue = mLooper.mQueue;) 因为系统一开始就创建好ui线程的时候也自动帮我们创建好了looper,也所以我们在主线程创建的时候可以不用关心handle具体依附于哪个looper。 但是如果在子线程中呢?子线程则没有这样好的待遇,它没有自动生成looper,所以我们在普通子线程中创建handle不指定好特定的looper就会报错,因为handle要好好依赖于一个消息队列,而消息队列由我们的looper产生的嘛~因此就有了new Handler((放一个looper过来!))这个方法,如 new Handler(getMainLooper())。

3注意点

下面说一下几个注意点,我在面试的时候看到面试官也会问错的问题。handle是如何实现异步的? 可能有的同学就会说,异步?就创建一个子线程啊!其实handle,runnable之类的并不会创建一个新线程!

1、handle可以在主线程中创建,而正在使用发送信息是在子线程,而不是handle自己new了一个子线程 2、handle创建的时候依赖于传入的looper,如果传入的looper是ui线程的looper,那么当在子线程调用的时候,handle发送的消息也是发送到ui线程的消息队列里面,由消息队列取出来再处理,所以才会有这样一个异步的操作。线程的looper一直在调用.loop方法,去查询消息队列有没有东西,有的话就取出来。 源码如下

public static void loop() { final Looper me = myLooper(); ...... //开始轮询,这个轮询可能阻塞 for (;;) { Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } ...... long origWorkSource = ThreadLocalWorkSource.setUid(msg.workSourceUid); try { msg.target.dispatchMessage(msg); if (observer != null) { observer.messageDispatched(token, msg); } dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0; } catch (Exception exception) { if (observer != null) { observer.dispatchingThrewException(token, msg, exception); } throw exception; } finally { ThreadLocalWorkSource.restore(origWorkSource); if (traceTag != 0) { Trace.traceEnd(traceTag); } } ...... msg.recycleUnchecked(); } } 最后

看到这里你应该对handle处理消息是如何进行的吧,感谢各位看官~



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3