导航:首页 > 操作系统 > androidhandler使用方法

androidhandler使用方法

发布时间:2022-10-01 15:03:49

① [android源码分析] - 异步通信Handler机制

一、问题:在Android启动后会在新进程里创建一个主线程,也叫UI线程( 非线程安全 )这个线程主要负责监听屏幕点击事件与界面绘制。当Application需要进行耗时操作如网络请求等,如直接在主线程进行容易发生ANR错误。所以会创建子线程来执行耗时任务,当子线程执行完毕需要通知UI线程并修改界面时,不可以直接在子线程修改UI,怎么办?

解决方法:Message Queue机制可以实现子线程与UI线程的通信。

该机制包括Handler、Message Queue、Looper。Handler可以把消息/ Runnable对象 发给Looper,由它把消息放入所属线程的消息队列中,然后Looper又会自动把消息队列里的消息/Runnable对象 广播 到所属线程里的Handler,由Handler处理接收到的消息或Runnable对象。

1、Handler

每次创建Handler对象时,它会自动绑定到创建它的线程上。如果是主线程则默认包含一个Message Queue,否则需要自己创建一个消息队列来存储。

Handler是多个线程通信的信使。比如在线程A中创建AHandler,给它绑定一个ALooper,同时创建属于A的消息队列AMessageQueue。然后在线程B中使用AHandler发送消息给ALooper,ALooper会把消息存入到AMessageQueue,然后再把AMessageQueue广播给A线程里的AHandler,它接收到消息会进行处理。从而实现通信。

2、Message Queue

在主线程里默认包含了一个消息队列不需要手动创建。在子线程里,使用Looper.prepare()方法后,会先检查子线程是否已有一个looper对象,如果有则无法创建,因为每个线程只能拥有一个消息队列。没有的话就为子线程创建一个消息队列。

Handler类包含Looper指针和MessageQueue指针,而Looper里包含实际MessageQueue与当前线程指针。

下面分别就UI线程和worker线程讲解handler创建过程:

首先,创建handler时,会自动检查当前线程是否包含looper对象,如果包含,则将handler内的消息队列指向looper内部的消息队列,否则,抛出异常请求执行looper.prepare()方法。

 - 在 UI线程 中,系统自动创建了Looper 对象,所以,直接new一个handler即可使用该机制;

- 在 worker线程 中,如果直接创建handler会抛出运行时异常-即通过查‘线程-value’映射表发现当前线程无looper对象。所以需要先调用Looper.prepare()方法。在prepare方法里,利用ThreadLocal<Looper>对象为当前线程创建一个Looper(利用了一个Values类,即一个Map映射表,专为thread存储value,此处为当前thread存储一个looper对象)。然后继续创建handler, 让handler内部的消息队列指向该looper的消息队列(这个很重要,让handler指向looper里的消息队列,即二者共享同一个消息队列,然后handler向这个消息队列发送消息,looper从这个消息队列获取消息) 。然后looper循环消息队列即可。当获取到message消息,会找出message对象里的target,即原始发送handler,从而回调handler的handleMessage() 方法进行处理。

 - handler与looper共享消息队列 ,所以handler发送消息只要入列,looper直接取消息即可。

 - 线程与looper映射表 :一个线程最多可以映射一个looper对象。通过查表可知当前线程是否包含looper,如果已经包含则不再创建新looper。

5、基于这样的机制是怎样实现线程隔离的,即在线程中通信呢。 

核心在于 每一个线程拥有自己的handler、message queue、looper体系 。而 每个线程的Handler是公开 的。B线程可以调用A线程的handler发送消息到A的共享消息队列去,然后A的looper会自动从共享消息队列取出消息进行处理。反之一样。

二、上面是基于子线程中利用主线程提供的Handler发送消息出去,然后主线程的Looper从消息队列中获取并处理。那么还有另外两种情况:

1、主线程发送消息到子线程中;

采用的方法和前面类似。要在子线程中实例化AHandler并设定处理消息的方法,同时由于子线程没有消息队列和Looper的轮询,所以要加上Looper.prepare(),Looper.loop()分别创建消息队列和开启轮询。然后在主线程中使用该AHandler去发送消息即可。

2、子线程A与子线程B之间的通信。

1、 Handler为什么能够实现不同线程的通信?核心点在哪?

不同线程之间,每个线程拥有自己的Handler、消息队列和Looper。Handler是公共的,线程可以通过使用目标线程的Handler对象来发送消息,这个消息会自动发送到所属线程的消息队列中去,线程自带的Looper对象会不断循环从里面取出消息并把消息发送给Handler,回调自身Handler的handlerMessage方法,从而实现了消息的线程间传递。

2、 Handler的核心是一种事件激活式(类似传递一个中断)的还是主要是用于传递大量数据的?重点在Message的内容,偏向于数据传输还是事件传输。

目前的理解,它所依赖的是消息队列,发送的自然是消息,即类似事件中断。

0、 Android消息处理机制(Handler、Looper、MessageQueue与Message)

1、 Handler、Looper源码阅读

2、 Android异步消息处理机制完全解析,带你从源码的角度彻底理解

谢谢!

wingjay

![](https://avatars0.githubusercontent.com/u/9619875?v=3&s=460)

② Android Handler那些事儿,消息屏障IdelHandlerANR

Handler 是Android SDK中用来处理异步消息的核心类,子线程可以通过handler来通知主线程进行ui更新。

备注:本文源码截图 基于Android sdk 28

Handler机制 消息发送主要流程如图

应用程序启动后,zygote fork一个应用进程后,和普通java程序一样,程序会首先执行ActivityThread中的main函数。在main函数中,程序首先会创建Looper对象并绑定到主线程中,然后开启loop循环。(ps:主线程loop循环不能退出)

在prepareMainLooper方法中,最终会创建Looper,MessageQueue对象 以及创建native层MessageQueue对象。

使用Handler.sendMessageXXX或这 postDedayXXX发送消息后,最终会调用到SendMessageAtTime方法中。

然后调用MessageQueue.enqueueMessage将消息存到消息队列中。

存入消息后,然后通过调用native方法 唤醒主线程进行消息处理。

当应用程序启动,做完一些必要工作之后,便会开启Loop循环,除非系统异常,否则该循环不会停止。loop循环中,主要做两件事,第一,从消息队列中取消息。第二,进行消息分发处理。

MessageQueue.next() 方法 通过调用 native方法 nativePollOnce(ptr, nextPollTimeoutMillis)实现无消息处理时,进入阻塞的功能。
当nextPollTimeoutMillis 值为0时,该方法会立刻返回;
当nextPollTimeoutMillis 值为-1时,该方法会无限阻塞,直到被唤醒;
当nextPollTimeoutMillis 值大于0时,该方法会将该值设置为超时时间,阻塞到达一定时间后,返回;

在loop循环中 ,通过调用 msg.target.dispatchMessage(msg) 进行消息的分发处理

使用当前线程的MessageQueue.addIdleHandler方法可以在消息队列中添加一个IdelHandler。

当MessageQueue 阻塞时,即当前线程空闲时,会回调IdleHandler中的方法;

当IdelHandler接口返回false时,表示该IdelHandler只执行一次,

a,延迟执行

例如,当启动Activity时,需要延时执行一些操作,以免启动过慢,我们常常使用以下方式延迟执行任务,但是在延迟时间上却不好控制。

其实,这时候使用IdelHandler 会更优雅

b,批量任务,任务密集,且只关注最终结果

例如,在开发一个IM类型的界面时,通常情况下,每次收到一个IM消息时,都会刷新一次界面,但是当短时间内, 收到多条消息时,就会刷新多次界面,容易造成卡顿,影响性能,此时就可以使用一个工作线程监听IM消息,在通过添加IdelHandler的方式通知界面刷新,避免短时间内多次刷新界面情况的发生。

在Android的消息机制中,其实有三种消息: 普通消息、异步消息及消息屏障。

消息屏障 也是一种消息,但是它的target为 null。可以通过MessageQueue中的postSyncBarrier方法发送一个消息屏障(该方法为私有,需要反射调用)。

在消息循环中,如果第一条消息就是屏障消息,就往后遍历,看看有没有异步消息:
如果没有,则无限休眠,等待被唤醒
如果有,就看离这个消息被触发时间还有多久,设置一个超时时间,继续休眠

异步消息 和普通消息一样,只不过它被设置setAsynchronous 为true。有了这个标志位,消息机制会对它有些特别的处理,我们稍后说。

所以 消息屏障和异步消息的作用 很明显,在设置消息屏障后,异步消息具有优先处理的权利。

这时候我们回顾将消息添加到消息队列中时,可以发现,其实并不是每一次添加消息时,都会唤醒线程。
当该消息插入到队列头时,会唤醒该线程;
当该消息没有插入到队列头,但队列头是屏障,且该消息是队列中 靠前的一个异步消息,则会唤醒线程,执行该消息;

调用MessageQueue.removeSyncBarrier 方法可以移除指定的消息屏障

ANR 即 Application Not Response, 是系统进程对应用行为的一种监控,如果应用程序没有在规定时间内完成任务的话,就会引起ANR。

ANR类型

Service Timeout : 前台服务20s, 后台服务200s

BroadcastQueue Timeout : 前台广播 10s,后台广播60s

ContentPrivider Timeout : 10s

InputDispatching Timeout : 5s

比如,在启动一个服务时, AMS端通过应用进程的Binder对象创建Service, 在scheleCreateService()方法中 会调用到当前service的onCreate()生命周期函数;

bumpServiceExecutingLocked()方法内部实际上会调用到scheleServiceTimeoutLocked()方法,发送一个ActivityManagerService.SERVICE_TIMEOUT_MSG类型消息到AMS工作线程中。

消息的延时时间,如果是前台服务,延时20s, 如果是后台服务,延时200s;

如果Service的创建 工作在 上诉消息的延时时间内完成,则会移除该消息,

否则,在Handler正常收到这个消息后,就会进行服务超时处理,即弹出ANR对话框。

复杂情况下,可能会频繁调用sendMessage 往消息队列中,添加消息,导致消息积压,造成卡顿,

1,重复消息过滤

频繁发送同类型消息时,有可能队列中之前的消息还没有处理,又发了一条相同类型的消息,更新之前的数据,这时候,可以采用移除前一个消息的方法,优化消息队列。

2,互斥消息取消

在发送消息时,优先将消息队列中还未处理的信息已经过时的消息 移除,优化队列

3,队列优化-复用消息

创建消息时,优先采用之前回收的消息,避免重复创建对象,引起GC

完~
(如果错误或不足,望指出, 大家共同进步)

③ Android中Handler的使用方法

主线程中创建handlerhandler的引用注入到adapteradapter里通过handler的引用发送message主线程中处理message

④ Android多线程的四种方式:Handler、AsyncTask、ThreadPoolExector、IntentService

     异步通信机制,将工作线程中需更新UI的操作信息 传递到 UI主线程,从而实现 工作线程对UI的更新处理,最终实现异步消息的处理。Handler不仅仅能将子线程的数据传递给主线程,它能实现任意两个线程的数据传递。

(1)Message

    Message 可以在线程之间传递消息。可以在它的内部携带少量数据,用于在不同线程之间进行数据交换。除了 what 字段,还可以使用 arg1 和 arg2 来携带整型数据,使用 obj 来携带 Object 数据。

(2) Handler

    Handler 作为处理中心,用于发送(sendMessage 系列方法)与处理消息(handleMessage 方法)。

(3) MessageQueue

    MessageQueue 用于存放所有通过 Handler 发送的消息。这部分消息会一直存放在消息队列中,直到被处理。每个线程中只会有一个 MessageQueue 对象

(4) Looper

    Looper 用于管理 MessageQueue 队列,Looper对象通过loop()方法开启了一个死循环——for (;;){},不断地从looper内的MessageQueue中取出Message,并传递到 Handler 的 handleMessage() 方法中。每个线程中只会有一个 Looper 对象。

    AsyncTask 是一种轻量级的任务异步类,可以在后台子线程执行任务,且将执行进度及执行结果传递给 UI 线程。

(1)onPreExecute()

    在 UI 线程上工作,在任务执行 doInBackground() 之前调用。此步骤通常用于设置任务,例如在用户界面中显示进度条。

(2)doInBackground(Params... params)

    在子线程中工作,在 onPreExecute() 方法结束后执行,这一步被用于在后台执行长时间的任务,Params 参数通过 execute(Params) 方法被传递到此方法中。任务执行结束后,将结果传递给 onPostExecute(Result) 方法,同时我们可以通过 publishProgress(Progress) 方法,将执行进度发送给 onProgressUpdate(Progress) 方法。

(3)onProgressUpdate(Progress... values)

    在 UI 线程上工作,会在 doInBackground() 中调用 publishProgress(Progress) 方法后执行,此方法用于在后台计算仍在执行时(也就是 doInBackgound() 还在执行时)将计算执行进度通过 UI 显示出来。例如,可以通过动画进度条或显示文本字段中的日志,从而方便用户知道后台任务执行的进度。

(4)onPostExecute(Result result)

    在 UI 线程上工作,在任务执行完毕(即 doInBackground(Result) 执行完毕)并将执行结果传过来的时候工作。

使用规则:

(1)AsyncTask 是个抽象类,所以要创建它的子类实现抽象方法

(1)AsyncTask 类必须是在 UI 线程中被加载,但在Android 4.1(API 16)开始,就能被自动加载完成。

(2)AsyncTask 类的实例对象必须在 UI 线程中被创建。

(3)execute() 方法必须是在 UI 线程中被调用。

(4)不要手动调用方法 onPreExecute()、onPostExecute()、doInBackground()、onProgressUpdate()

(5)任务只能执行一次(如果尝试第二次执行,将抛出异常)。即一个AsyncTask对象只能调用一次execute()方法。

原理:

          其源码中原理还是 Thread 与 Handler 的实现,其包含 两个线程池,一个 Handler,如下所示:

名称类型作用

SERIAL_EXECUTOR线程池分发任务,串行分发,一次只分发一个任务

THREAD_POOL_EXECUTOR线程池执行任务,并行执行,执行的任务由 SERIAL_EXECUTOR 分发

InternalHandlerHandler负责子线程与主线程的沟通,通知主线程做 UI 工作

    一方面减少了每个并行任务独自建立线程的开销,另一方面可以管理多个并发线程的公共资源,从而提高了多线程的效率。所以ThreadPoolExecutor比较适合一组任务的执行。Executors利用工厂模式对ThreadPoolExecutor进行了封装。

Executors提供了四种创建ExecutorService的方法,他们的使用场景如下:

1. Executors.newFixedThreadPool()

    创建一个定长的线程池,每提交一个任务就创建一个线程,直到达到池的最大长度,这时线程池会保持长度不再变化。

当线程处于空闲状态时,它们并不会被回收,除非线程池被关闭。当所有的线程都处于活动状态时,新任务都会处于等待状态,直到有线程空闲出来。

只有核心线程并且不会被回收,能够更加快速的响应外界的请求。

2. Executors.newCachedThreadPool()

    创建一个可缓存的线程池,如果当前线程池的长度超过了处理的需要时,它可以灵活的回收空闲的线程,当需要增加时,它可以灵活的添加新的线程,而不会对池的长度作任何限制

    线程数量不定的线程池,只有非核心线程,最大线程数为 Integer.MAX_VALUE。当线程池中的线程都处于活动状态时,线程池会创建新的线程来处理新任务,否则利用空闲的线程来处理新任务。线程池中的空闲线程具有超时机制,为 60s。

    任务队列相当于一个空集合,导致任何任务都会立即被执行,适合执行大量耗时较少的任务。当整个线程池都处于限制状态时,线程池中的线程都会超时而被停止。

3. Executors.newScheledThreadPool()

    创建一个定长的线程池,而且支持定时的以及周期性的任务执行,类似于Timer。

    非核心线程数没有限制,并且非核心线程闲置的时候立即回收,主要用于执行定时任务和具有固定周期的重复任务。

4. Executors.newSingleThreadExecutor()

    创建一个单线程化的executor,它只创建唯一的worker线程来执行任务

    只有一个核心线程,保证所有的任务都在一个线程中顺序执行,意义在于不需要处理线程同步的问题。

    一般用于执行后台耗时任务,当任务执行完成会自动停止;同时由于它是一个服务,优先级要远远高于线程,更不容易被系统杀死,因此比较适合执行一些高优先级的后台任务。

使用步骤:创建IntentService的子类,重写onHandleIntent方法,在onHandleIntent中执行耗时任务

    原理:在源码实现上,IntentService封装了HandlerThread和Handler。onHandleIntent方法结束后会调用IntentService的stopSelf(int startId)方法尝试停止服务。

    IntentService的内部是通过消息的方式请求HandlerThread执行任务,HandlerThread内部又是一种使用Handler的Thread,这就意味着IntentService和Looper一样是顺序执行后台任务的

(HandlerThread:封装了Handler + ThreadHandlerThread适合在有需要一个工作线程(非UI线程)+任务的等待队列的形式,优点是不会有堵塞,减少了对性能的消耗,缺点是不能同时进行多个任务的处理,需要等待进行处理。处理效率低,可以当成一个轻量级的线程池来用)

⑤ android 的API的handler翻译

继承顺序:java.lang.Object-->android.os.Handler

直接子类:AsyncQueryHandler,HttpAuthHandler,SslErrorHandler

public class Handler extends Object

一个Handler允许你传递、处理Message和Runnable对象,通过相关联的thread的消息队列(MessageQueue).每个handler实例都与一个thread相关联和特定的消息队列。当你创建了一个新的Handler,他就绑定到了这个thread的thread或者message队列,而这个thread从创建的地点将传递消息和runnables到那个消息队列,且处理那些从消息队列中出来消息。

有两种主要的使用方式,1、有计划的处理message和runnable,在未来的某个时刻。2、在非你的另外的线程上执行一个方法。

计划消息使用下列方法处理:post(java.lang.Runnable),postAtTime(Runnable,long),postDelayer(java.lang.Runnable,long),sendEmptyMessage(int),sendMessage(android.os.Message),sendMessageAtTime(android.os.Message,long),和sendMessageDelayed(android.os.Message,long)。消息队列调用post方法允许你讲Runnable对象压入队列,当被接收的时候。当Handler的handleMessage方法处理一束Message包含的数据的时候,允许你压入message进入队列(需要你实现一个Handler的子类)。

当提交或者传递一个Handler的时候,你既可以让item处理与消息队列准备好一样快,或者指定一个延迟在他被处理或者被处理前的绝对时间间隔。后两者需要你实现时间、轨迹和其他的时间基本行为。

当应用创建好一个process,他的主线程决定运行一个消息队列,这个队列接管着应用最高等级的对象(activities,broadcast,receivers,etc)和他们创建的任意的窗口。你可以创建你的自己的threads和通讯,通过一个Handler与主线程完成回调。在完成之前调用相同的post或者sendMessage方法,但是通过新的thread.给定的Runnable或者Message将被添加到Handler的消息队列,且在适当的时候完成处理。

一、嵌套类摘要

 Handler.Callback

在你实例化一个Handler的时候你可以使用Callback接口用来避免必须实现你自己的Handler子类。、

二、构造方法摘要

Handler()

默认的构造方法使得该handler与当前的thread队列相关联。

Handler(Handler.Callback callback)

与当前的thread队列想关联且在回调接口中可以处理message

Handler(Looper looper)

使用自定义的队列代替默认的队列。

Handler(Looper looper,Handler.Callback callback)

使用自定义的队列代替默认的队列且在回调接口中处理message

三、方法摘要

dispatchMessage(Message msg):处理系统的信息

mp(Printer pw, String prefix)

getLooper()

handleMessage(Message msg)子类必须实现这个来接收消息

hasMessage(int what):检查消息中的what是否含有消息且obj在队列中是否是对象。

obtainMessage():从全局message池返回一个新的Message

obtainMessage(int what):功能同上,除了能够设置返回消息中的member属性

obtainMessage(int what,int arg1,int arg2):功能同obtainMessage(),除了能设置what arg1, arg2这些属性。

obtainMessage(int what,int arg1,int arg2,Object obj):功能同不带参数的方法,除了能够设置what ,obj,arg1,arg2值。

obtainMessage(int what,Object obj):功能同无参数方法一样,除了能设置what和obj属性值。

post(Runnable r):使得Runnable r添加到消息队列。

postAtFrontOfQueue(Runnable r):提交一个消息到一个实现了Runnable的对象

postAtTime(Runnable r,long uptimeMillis):使得Runnable r被添加到消息队列,在由uptimeMills给定的特定时间

postAtTime(Runnable r , Object token, long uptimeMills):使得Runnable r添加到消息队列,在由uptimeMills给定的特定时间运行。

postDelayer(Runnable r , long delayMillis):使得Runnable r被添加到队列,在由指定的时间后运行。

removeCallbacks(Runnable r):移除在消息队列中的没有提交的Runnable r

removeCallbacks(Runnable r,Object token):移除在消息队列中使用Object 的token的没有提交的Runnable r.

removeCallbacksAndMessage(Object token):移除在回调函数中没有提交的消息且发送消息的obj是token

void removeMessages (int what)

Remove any pending posts of messages with code 'what' that are in the message queue.

void removeMessages (int what, Object object)

Remove any pending posts of messages with code 'what' and whose obj is 'object' that are in the message queue.

boolean sendEmptyMessage (int what)

Sends a Message containing only the what value.

boolean sendEmptyMessageAtTime (int what, long uptimeMillis)

Sends a Message containing only the what value, to be delivered at a specific time.

boolean sendEmptyMessageDelayed (int what, long delayMillis)

Sends a Message containing only the what value, to be delivered after the specified amount of time elapses.

boolean sendMessage ( Message msg)

Pushes a message onto the end of the message queue after all pending messages before the current time.

boolean sendMessageAtFrontOfQueue ( Message msg)

Enqueue a message at the front of the message queue, to be processed on the next iteration of the message loop.

boolean sendMessageAtTime ( Message msg, long uptimeMillis)

Enqueue a message into the message queue after all pending messages before the absolute time (in milliseconds)uptimeMillis.

boolean sendMessageDelayed ( Message msg, long delayMillis)

Enqueue a message into the message queue after all pending messages before (current time + delayMillis).

String toString ()

Returns a string containing a concise, human-readable description of this object.

⑥ android中handler的使用

Handler这部分我也在用,模仿例子套着用,主要用于子线程向主程序发消息,让Handler对象处理。你的疑问我也有,这new Handler(){},只是一瞬间就结束的,可它仍时刻监视着自已的消息以便随时再处理,这似乎有点不符常规令人不解,但细想一下,这就象一个按钮控件对象,
你点击一下,它就能响应一次点击处理事件。

⑦ Android中介绍Handler的几种用法

第一种

第二种

第三种

如果还有其他用法,请高人赐教。
ps:孔乙己先生,handler有几种用法啊!

⑧ Android Handler消息机制

跨线程通信。当子线程中进行耗时操作后需要更新UI时,通过Handler将有关UI的操作切换到主线程中执行。
四要素:
Message(消息):需要被传递的消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,最终由Handler处理。
MessageQueue(消息队列):用来存放Handler发送过来的消息,内部通过单链表的数据结构来维护消息列表,等待Looper的抽取。
Handler(处理者):负责Message的发送及处理。通过 Handler.sendMessage() 向消息池发送各种消息事件;通过 Handler.handleMessage() 处理相应的消息事件。
Looper(消息泵):通过Looper.loop()不断地从MessageQueue中抽取Message,按分发机制将消息分发给目标处理者。
Handler.sendMessage()发送消息时,会通过MessageQueue.enqueueMessage()向MessageQueue中添加一条消息;
通过Looper.loop()开启循环后,不断轮询调用MessageQueue.next();
调用目标Handler.dispatchMessage()去传递消息,目标Handler收到消息后调用Handler.handlerMessage()处理消息。

⑨ Android Handler机制 怎么用

Handler对象与其调用者在同一线程中,如果在Handler中设置了延时操作,则调用线程也会堵塞。每个Handler对象都会绑定一个Looper对象,每个Looper对象对应一个消息队列(MessageQueue)。如果在创建Handler时不指定与其绑定的Looper对象,系统默认会将当前线程的Looper绑定到该Handler上。
在主线程中,可以直接使用new Handler()创建Handler对象,其将自动与主线程的Looper对象绑定;在非主线程中直接这样创建Handler则会报错,因为Android系统默认情况下非主线程中没有开启Looper,而Handler对象必须绑定Looper对象。这种情况下,需先在该线程中手动开启Looper(Looper.prepare()-->Looper.loop()),然后将其绑定到Handler对象上;或者通过Looper.getMainLooper(),获得主线程的Looper,将其绑定到此Handler对象上。
Handler发送的消息都会加入到Looper的MessageQueue中。一说Handler包含两个队列:线程队列和消息队列;使用Handler.post()可以将线程对象加入到线程队列中;使用Handler.sendMessage()可以将消息对象加入到消息队列中。通过源码分析证实,Handler只有一个消息队列,即MessageQueue。通过post()传进去的线程对象将会被封装成消息对象后传入MessageQueue。
使用post()将线程对象放到消息队列中后,当Looper轮询到该线程执行时,实际上并不会单独开启一个新线程,而仍然在当前Looper绑定的线程中执行,Handler只是调用了该线程对象的run()而已。如,在子线程中定义了更新UI的指令,若直接开启将该线程执行,则会报错;而通过post()将其加入到主线程的Looper中并执行,就可以实现UI的更新。
使用sendMessage()将消息对象加入到消息队列后,当Looper轮询到该消息时,就会调用Handler的handleMessage()来对其进行处理。再以更新UI为例,使用这种方法的话,就先将主线程的Looper绑定在Handler对象上,重载handleMessage()来处理UI更新,然后向其发送消息就可以了。

⑩ 能讲讲Android的Handler机制吗

Android的Handler机制是通俗讲为了互相发消息,一般是子线程给主线程发消息完成相应操作。

安卓中最常见的操作是子线程操作完事后得到数据想更新UI,安卓有规定不允许在子线程中刷新UI,所以Handler出现了。

使用和理解大致步骤。

  1. 创建全局Handler对象handler,然后在主线程中初始化它(一般在oncreate中),把它的handmessage里面的方法重写,这个方法是收到子线程发给它的消息后执行的逻辑。

  2. 在子线程中获取数据,调用handler.sendmessage,把要发的消息放在message中。message会添加到Messagequue(消息队列中,handler创建就带的)。

3.对象handler被创建和初始化的时候,系统自动会启动Handler.looper,也就是一个消息轮询器,它不断的去查看有没有消息进入到Messagequue(消息队列中),有就取出交给handler的handmessage去处理。//这段逻辑是系统自动执行,理解就行。*纯手打,不骗人~~~

阅读全文

与androidhandler使用方法相关的资料

热点内容
滴滴金融app被下架如何还款 浏览:208
jpg转换成pdf免费软件 浏览:741
范里安pdf 浏览:443
伪造pdf 浏览:75
能删除android文件夹吗 浏览:446
LINUX使用V2ray 浏览:797
找人帮忙注册app推广是什么 浏览:820
独立服务器如何恢复初始化 浏览:11
优秀到不能被忽视pdf 浏览:316
导游程序员家政 浏览:586
22乘28的快速算法 浏览:338
软通动力程序员节2021 浏览:845
安卓系统如何卸载安装包 浏览:870
短信删除助手文件夹 浏览:688
java办公自动化 浏览:342
php中超链接 浏览:254
linux默认路由设置 浏览:36
linux如何挂载iso 浏览:432
vs程序换文件夹后不能编译 浏览:558
安卓源码编译输入脚本没反应 浏览:47