android消息机制,异步和多线程

前言
在xxxx1.92正式版的时候付费购买曾单独封装了一个流程PaymentFlow并继承于Handler,调用方只要依据这个流程创建流程实例并触发开始,实例即可依据设定的支付流程完成.但在异步和多线程方面却有’ java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()’的问题.最近在作风网络库的替换,网络库使用的Handler的继承类MessageHandler作为回调.同样也存在多线程的异步调用或诸塞的问题,所以在此就将Handler的机制在研究一遍.

1.Handler,Looper,Activity
Android应用程序是消息驱动的,并通过Looper,Handler来实现消息循环机制,且是针对线程的. 一个线程可以存在(当然也可以不存在)一个消息队列和一个消息循环(Looper),特定线程的消息只能分发给本线程,不能进行跨线程,跨进程通讯.但是创建的工作线程默认是没有消息循环和消息队列的,如果想让该线程具有消息队列和消息循环,需要在线程中首先调用Looper.prepare()来创建消息队列,然后调用Looper.loop()进入消息循环. Handler的作用是把消息加入特定的(Looper)消息队列中,并分发和处理该消息队列中的消息.构造Handler的时候可以指定一个Looper对象,如果不指定则利用当前线程的Looper创建.Activity是一个UI线程,运行于主线程中,Android系统在启动的时候会为Activity创建一个消息队列和消息循环(Looper).一个Activity中可以创建多个工作线程或者其他的组件,如果这些线程或者组件把他们的消息放入Activity的主线程消息队列,那么该消息就会在主线程中处理了.之间的关系如下图所示



103104_uUTr_57046.jpg

我们可以写个测试用例在Activity和Handler中分别打印出线程编号就明白在默认情况下(例如: private Handler handler = new Handler();),Activity和Handler是在同个线程上运行的.

如果一个线程中调用Looper.prepare(),那么系统就会自动的为该线程建立一个消息队列,然后调用 Looper.loop();之后就进入了消息循环,这个之后就可以发消息、取消息、和处理消息.这个如何发送消息和如何处理消息可以在其他的线程中通过Handle来做,但前提是我们的Hanle知道这个子线程的Looper,但是你如果不是在子线程运行 Looper.myLooper(),一般是得不到子线程的looper的.

除此也可以通过创建HandlerThread来为Handler来创建一个新得的Looper并赋予Handler,这样Handler就会在非主线程执行.

HandlerThread thread=newHandlerThread(“handler_thread”));

thread.start();

Handler m=newHandler(thread.getLooper());

2.Handler与Thread的区别
Handler与调用者处于同一线程,如果Handler里面做耗时的动作,调用者线程会阻塞.Android UI操作不是线程安全的,并且这些操作必须在UI线程中执行.Android提供了几种基本的可以在其他线程中处理UI操作的方案,包括Activity 的runOnUiThread(Runnable),View的post以及1.5版本的工具类AsyncTask等方案都采用了 Handler,Handler的post对线程的处理也不是真正start一个新的线程,而是直接调用了线程的run方法.



3.Handler对于Message的处理不是并发的
一个Looper 只有处理完一条Message才会读取下一条,所以消息的处理是阻塞形式的.但是如果用不同的Looper则能达到并发的目的.Service 中,onStart的执行也是阻塞的.如果一个startService在onStart执行完成之前,再次条用startService也会阻塞.如果希望能尽快的执行onStart则可以在onStart中使用handler,因为Message的send是非阻塞的.如果要是不同消息的处理也是并发 的,则可以用不同的Looper实例化Handler.



4.资源回收
向Handler对象发送类似new Message()形式的空Message可以达到清空Message的目的,这种做法与getLooper().quit()的做法是一样的.如果利用的资源较多,应及时清理.

更多相关文章

  1. Android中的线程之线程基础(synchronized,wait,sleep,yield,notify )
  2. 子线程更新UI的方法
  3. Android能否在子线程中更新UI呢?
  4. Android多线程之图解Handler Looper MessageQueue Message
  5. android异步任务完成后再执行主线程任务

随机推荐

  1. Android(安卓)4.4 KitKat NotificationMa
  2. 第一部分:如何在iOS和Android上选择一个J
  3. Android SharePreferences源码解析
  4. Android 开发 之 折叠布局(CollapsingTool
  5. 网页 Android(安卓)套壳
  6. 20180505_android传感器种类及获取
  7. 【Android】Navigation实现页面跳转
  8. android2.2中默认浏览器无法使用手势放大
  9. android tips—NumberPicker,DataPicker,Ti
  10. Android 判断应用是否开启了通知权限