Android 线程简单分析(一)
Android 并发之synchronized锁住的是代码还是对象(二)
Android 并发之CountDownLatch、CyclicBarrier的简单应用(三)
Android 并发HashMap和ConcurrentHashMap的简单应用(四)(待发布)
Android 并发之Lock、ReadWriteLock和Condition的简单应用(五)
Android 并发之CAS(原子操作)简单介绍(六)
Android 并发Kotlin协程的重要性(七)(待发布)
Android 并发之AsyncTask原理分析(八)
Android 并发之Handler、Looper、MessageQueue和ThreadLocal消息机制原理分析(九)
Android 并发之HandlerThread和IntentService原理分析(十)

首先HandlerThread是一个线程而不是Handler,为了讲解HandlerThread,所以不得不提Looper轮训器,如果看过Handler源码的同学应该很清楚,Handler 发送消息到Looper的MessageQueue中,然后Looper的loop方中不断轮训的从MessageQueue中取出消息,并分发给Handler处理,即loop方法在那个线程调用,那么消息的处理就在那个险种中:

for (;;) {        Message msg = queue.next(); // might block        if (msg == null) {        //没有消息表明消息队列正在退出。            return;        }        //消息分发,Message的target持有指定Handler的的引用,分发给指定的Handler处理消息         msg.target.dispatchMessage(msg);        //回收message并放入消息池中        msg.recycleUnchecked();    }

明白的Looper的作用之后,接下看看HandlerThread,应该很好理解,HandlerThread继承Thread,不是一个Handler,其封装了Handler、Thread,官方是这样解析这个类,一个很方便的用于启动一个具有Looper的新线程。 然后可以使用这个Looper创建Handler类。必须要先调用start方法:

 @Overridepublic void run() {    mTid = Process.myTid();    Looper.prepare();    synchronized (this) {        mLooper = Looper.myLooper();        notifyAll();//唤醒等待的线程    }    Process.setThreadPriority(mPriority);    onLooperPrepared();    Looper.loop();    mTid = -1;} public Looper getLooper() {    if (!isAlive()) {        return null;    }        // 如果线程已经启动,一直等待知道Looper被创建。    synchronized (this) {        while (isAlive() && mLooper == null) {            try {                wait();            } catch (InterruptedException e) {            }        }    }    return mLooper;}

这两个就是主要的代码,所以我前面说了,必须要调用start方法启动线程,在run方法中创建Looper,这样我们如果需要在子线程中处理消息,可以使用这个Looper来创建Handler, getLooper()方法就是拿到HandlerThread的创建Looper;

IntentService:

讲完HandlerThread,必然就是IntentService了,其也是一个Service,只是其在工作线程中运行,但是他是每次提交任务,也是在同一个线程中串行执行,IntentService其分装了HandlerThread,并使用HandlerThread的Looper作为处理消息的线程:

    @Overridepublic void onCreate() {    super.onCreate();    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");    thread.start();    mServiceLooper = thread.getLooper();    mServiceHandler = new ServiceHandler(mServiceLooper);}

在Oncreate生命周期方法中创建了HandlerThread ,并使用期Looper创建ServiceHandler,service的声明周期是:首次创建会调用oncreate方法,之后都会调用onStartCommand->onStart所以:

  @Overridepublic void onStart(@Nullable Intent intent, int startId) {    Message msg = mServiceHandler.obtainMessage();    msg.arg1 = startId;    msg.obj = intent;    mServiceHandler.sendMessage(msg);}

每次启动IntentService都会调用mServiceHandler.sendMessage(msg);发消息,并在handler处理消息,所以这些消息都是串行执行的:

private final class ServiceHandler extends Handler {    public ServiceHandler(Looper looper) {        super(looper);    }    @Override    public void handleMessage(Message msg) {        onHandleIntent((Intent)msg.obj);        stopSelf(msg.arg1);    }}

当onHandleIntent方法执行结束之后,IntentService会尝试通过stopSelf(int startId)来尝试停止服务。之所以不用stopSelf()来停止服务,是因为stopSelf()会立刻停止服务,而stopSelf(int startId)则会等待所有的消息都处理完毕才回终止服务。一般来说,stopSelf(int startId)在尝试停止服务之前会判断最近启动服务的次数是否和startId相等,如果相等则立刻停止服务。

如果服务停止,会把所有的消息清除

 @Overridepublic void onDestroy() {    mServiceLooper.quit();}

为什么不建议通过 bindService() 启动 IntentService?

  • 手动调用bindService()后,自动调用内部方法:onCreate()、onBind()
  • 手动调用startService()后,自动调用内部方法:onCreate()、onStartCommand、onStart,因为bindService后没有回调onStart,所以没有发送消息,就不会执行 onHandleIntent()方法。
  • 时使用startService()启动服务、BindService()绑定服务的生命周期:
    onCreate()、onStartCommand、onStart、onBind()

当然如果你要是同时使用startService()启动服务、BindService()绑定服务的生命周期,那我就无话可说了,我是觉得可行,具体需求我没用过,如果哪位同学有这种需求,可以讨论哦。

更多相关文章

  1. android消息处理机制学习(一)-Handler,Message,MessageQueue,Loope
  2. Android(安卓)开发指南文档的部分中文翻译
  3. Android/java 多线程(六)-AsyncTask使用详解及源码分析
  4. Android(安卓)第七天(下午)
  5. android dialog小结
  6. Android(安卓)多线程之线程池
  7. Android(安卓)Handler机制8之消息的取出与消息的其他操作
  8. Android窗口治理机制
  9. Android安全加密:消息摘要Message Digest

随机推荐

  1. CSDN精选Android开发博客
  2. Android 中文 API (35) —— ImageSwitcher
  3. Android最佳性能实践(一)——合理管理内
  4. ubuntu NDK 的安装
  5. My Android成长之路(四)——【xml解析之X
  6. Android EditText不弹出软键盘
  7. Sending email without user interaction
  8. android 使用Lottie实现Android动画
  9. Android中onContextItemSelected不响应
  10. android开发 列表显示(ListView)