Android面试题:消息机制与异步相关

 1.Android中Looper的实现原理,为什么调用Looper.prepare()就在当前线程关联了一个Looper对象,它是如何实现的。
(1)、线程间通信机制
如在A、B两个子线程之间需要传递消息,首先给每个子线程绑定一套handler、looper、messagequeue机制,然后这三个对象都与其所属线程对应。然后A线程通过调用B线程的Handler对象,发送消息。这个消息会被Handler发送到B线程的messagequeue中,而属于B线程的Looper对象一直在for循环里无限遍历MessageQueue, 一旦发现该消息队列里收到了新的消息,就会去对消息进行处理,处理过程中会回调自身Handler的heandleMessage方法。从而实现了不同线程间通信。
(2)、Looper实现原理
Looper类里包含一个消息队列对象和一个线程对象。当创建Looper时,会自动创建一个消息队列,同时将内部线程对象指向创建Looper的线程。当开启Looper后(looper.loop()),会自动进入无限for循环中,不断去遍历消息队列,如果没有消息则阻塞,有消息则回调handler的handlemessage方法进行处理。
(3)、Looper.prepare()
首先,要使用Looper机制一般会在当前线程中创建Handler对象,里面会自动创建一个looper对象和消息队列,这里面的消息队列属于当前线程空间。但此时的looper还不会去遍历,也没有绑定到当前线程。其中,looper对象内部也包含一个空消息队列对象和空线程。通过Looper.prepare()方法,先让该消息队列指向当前线程的消息队列,让空线程也指向当前线程。从而实现了绑定。
2.简述Andriod如何处理UI与耗时操作的通信,有哪些方式及各自的优缺点。
主要有三种方法,一为Handler,二为AsyncTask,三为自己开子线程执行耗时操作,然后调用Activity的runOnUiThread()方法更新ui;
(1).handler机制是,在主线程中创建handler对象,当执行耗时操作时,新建一个线程,在这个线程中执行耗时操作,通过调用handler的sendMessage,post等方法,更新ui界面;
(2).AsyncTask本质上是一个线程池,所有的异步任务都会在这个线程池中的工作线程中执行,当需要操作ui界面时,会和工作线程通过handler传递消息。
(3).自己开子线程执行耗时操作,然后调用Activity的runOnUiThread()方法更新ui,这种方法需要把context对象强制转换成activity后使用
handler机制的优点是 结构清晰,功能明确,但是代码过多;
asyncTask简单,快捷,但是可能会新开大量线程,消耗系统资源,造成FC
第三种方法最好用,代码也非常简单,只是需要传递context对象

3. Handler、 Thread 和 HandlerThread 的差别
Handler:Android消息处理机制,可以实现异步更新UI,线程间通信,更新Ui是主线程和子线程之间的通信;

子线程和子线程之间的通信通过Handler和Thread实现的(需要自己实现Looper),

HandlerThread相当于Handler+Thread

4.主线程中的Looper.loop()一直无限循环检测消息队列中是否有新消息为什么不会造成ANR?
 Android.app.ActivityThread中的main方法进行循环的获取消息,app入口程序为主线程创建了消息队列,Looper会一直循环的读取MessageQueue中的消息,

public static void main(String[] args) { 
.... 
//创建Looper和MessageQueue对象,用于处理主线程的消息 Looper.prepareMainLooper(); 
//创建ActivityThread对象 
ActivityThread thread = new ActivityThread(); 
//建立Binder通道 (创建新线程) 
thread.attach(false); 
Looper.loop(); 
//消息循环运行 
throw new RuntimeException("Main thread loop unexpectedly exited"); 
}

承载ActivityThread的主线程就是由Zygote fork而创建的进程。
在ActivityThread的main方法中,先为主线程创建了消息队列,然后再消息循环处理前开启了子线程用于处理其他的事务,比如Activity的生命周期的处理过程,

5.Handler 机制及底层实现
 Handler内部维护了一个消息队列MessageQueue,Handler会一直循环接收由handler过来的Message对象,由handleMessage方法处理,根据msg.what判断,Handler运行在主线程中,所以根据发送过来的消息可以进行UI的更新操作,解决了不能再非UI线程中更新UI的问题。

猜你喜欢

转载自blog.csdn.net/yyg_2015/article/details/77792125