美文网首页
IntentService源码分析

IntentService源码分析

作者: maimingliang | 来源:发表于2017-01-16 23:13 被阅读36次

    IntentService简介

    IntentService is a base class for {@link Service}s that handle asynchronous requests (expressed as {@link Intent}s) on demand. Clients send requests through
    {@linkandroid.content.Context#startService(Intent)} calls; the service is started as needed, handles each Intent in turn using a worker
    thread, and stops itself when it runs out of work.

    IntentService是Service的子类,比普通的Service增加了额外的功能,先看看Service的存在的两个问题:

    1. Service不会专门启动一条单独的进程,Service与它所在应用位于同一个进程中;
    2. Service也不是专门一条新线程,运行在主线程,因此不应该在Service中直接处理耗时的任务;

    IntentService特征

    会创建独立的worker线程来处理所有的Intent请求;
    会创建独立的worker线程来处理onHandleIntent()方法实现的代码,无需处理多线程问题;
    所有请求处理完成后,IntentService会自动停止,无需调用stopSelf()方法停止Service;
    为Service的onStartCommand提供默认实现,将请求Intent添加到队列中

    IntentService的源码

    IntentService的源码只有100多行,看起来也很容易理解,里面有些思想值得借鉴,学习。

    onCreate方法:

    
    @Override
        public void onCreate() {
            // TODO: It would be nice to have an option to hold a partial wakelock
            // during processing, and to have a static startService(Context, Intent)
            // method that would launch the service & hand off a wakelock.
    
            super.onCreate();
            HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
            thread.start();
    
            mServiceLooper = thread.getLooper();
            mServiceHandler = new ServiceHandler(mServiceLooper);
        }
    
    
    1. 通过HandlerThread获取到Looper对象
    2. 传入Looper对象创建出ServiceHandler

    HandlerThread继承于Thread ,看看getLooper()方法

    
     public Looper getLooper() {
            if (!isAlive()) {
                return null;
            }
            
            // If the thread has been started, wait until the looper has been created.
            synchronized (this) {
                while (isAlive() && mLooper == null) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                    }
                }
            }
            return mLooper;
        }
    
    

    可以看到其实这里设计得很巧妙,由于HandlerThread继承于Thread的,如果在run方法做一些耗时的操作,可能导致Looper对象还没来得急创建。进入run方法:

    
        @Override
        public void run() {
            mTid = Process.myTid();
            Looper.prepare();
            synchronized (this) {
                mLooper = Looper.myLooper();
                notifyAll();
            }
            Process.setThreadPriority(mPriority);
            onLooperPrepared();
            Looper.loop();
            mTid = -1;
        }
    
    

    当new Looper对象,调用notifyAll(),从而保证了Looper对象能被成功的创建。设计的非常巧妙,值得学习。

    进入onStart什么周期方法:

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

    mServiceHandler 继承于 Handler ,既然mServiceHandler 是Handler ,看看 handleMessage方法

    
      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);
            }
        }
    
    

    mServiceHandler的创建的传入的Looper的在子线程创建的,
    Handler类的handleMessage方法所在的线程决定于它的Looper所在的线程,因此Intent Service 可以在onHandleIntent 方法中处理耗时的操作。
    请求处理完成后,IntentService会调用stopSelf(msg.arg1)方法自动停止。

    看看onBind方法

     @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
    

    不建议通过 bindService() 启动 IntentService,在 onBind() 默认返回 null;不适合 bindService() 启动服务。

    总结

    1. 可以利用Handler去维护一个队列
    2. 如何保证在线程中正确的创建出对象。
    3. 有很多人会误解为Handler的功能是,当我们需要在子线程处理耗时的操作(例如访问网络,数据库的操作),而当耗时的操作完成后,需要更新UI,这就需要使用Handler来处理。
      其实并不是,Handler功能是能帮我们很容易的把任务切换回它所在的线程,Handler的handleMessage方法所在的线程决定于它的Looper所在的线程。

    END。

    相关文章

      网友评论

          本文标题:IntentService源码分析

          本文链接:https://www.haomeiwen.com/subject/olyubttx.html