Android IntentService源码分析

每天一篇系列:
强化知识体系,查漏补缺。
欢迎指正,共同学习!

IntentService是一个Android基础类,用于处理Intent类型的异步任务请求。当客户端调用android.content.Context#startService(Intent)发送请求时,Service服务被启动,且在其内部构建一个工作线程来处理Intent请求。当工作线程执行结束,Service服务会自动停止。
IntentService是一个抽象类,用户必须实现一个子类去继承它,且必须实现IntentService里面的抽象方法onHandleIntent来处理异步任务请求。

public class DownLoadService extends IntentService {

    public static final String TAG = "DownLoadService";
    //重写默认的构造方法
    public DownLoadService() {
        super("DownLoadService");
    }

    //在后台线程执行
    @Override
    protected void onHandleIntent(Intent intent) {
        int key = intent.getIntExtra("key", 0);
        String value = intent.getStringExtra("value");
        switch (key) {
            case 1:
                //模拟耗时任务1
                try {
                    Thread.sleep(3 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            case 2:
                //模拟耗时任务1
                try {
                    Thread.sleep(3 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            default:
                break;
        }

        Log.e(TAG, "\nthe current time is: " + System.currentTimeMillis()/1000
                + "\nthe Thread id is " + Thread.currentThread().getId()
                + "\nthe current task is " + value);
    }
}

IntentService源码分析:

public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper;
    private volatile ServiceHandler mServiceHandler;
    private String mName;
    private boolean mRedelivery;

    public IntentService(String name) {
        super();
        mName = name;
    }
    ...
}

首先IntentService继承了Service,生命周期还是从OnCreat,onStartCommand/onBind,onDestroy。只不过IntentService重写了这些方法,在子类中不需要再重写。

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

    protected abstract void onHandleIntent(Intent intent);

在onCreate()阶段,创建了HandlerThread,并且创建了一个Handler,Handler的Looper是HandlerThread的Looper。这样处理的话相当于创建一个带有消息队列的线程,耗时操作可以在HandlerThread这条线程中处理。可以看到Handler的消息都传递给onHandleIntent,而onHandleIntent是一个抽象方法,需要子类重写。这样也就是把耗时操作放置在HandlerThread线程中,用户可以重写onHandleIntent实现耗时操作处理,处理完毕后调用:

    stopSelf(msg.arg1);
    public final void stopSelf() {
        stopSelf(-1);
    }
    public final void stopSelf(int startId) {
        if (mActivityManager == null) {
            return;
        }
        try {
            mActivityManager.stopServiceToken(
                    new ComponentName(this, mClassName), mToken, startId);
        } catch (RemoteException ex) {
        }
    }

等待耗时操作处理完毕以后,IntentService就会自动退出,生命周期终止。

IntentService借助HandlerThread来完成了异步消息的处理,那么HandlerThread和Thread有什么区别呢?

HandlerThread handlerThread = new HandlerThread("test");
handlerThread.start();

HandlerThread源码分析:

public class HandlerThread extends Thread {
int mPriority;
    int mTid = -1;
    Looper mLooper;

    public HandlerThread(String name) {
        super(name);
        mPriority = Process.THREAD_PRIORITY_DEFAULT;
    }
    ...
}

HandlerThread继承于Thread,Thread内部肯定有run()方法,看看HandlerThread内部的run实现:

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

果然没错,可以看到调用start的时候,run函数开始执行:

    Looper.prepare();

多么熟悉的代码,还记得之前文章中分析的嘛,UI线程不也是这样创建Looper的。

    public static void prepare() {
        prepare(true);
    }

    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }

在run方法里面新建了一个Looper,并且同步了notifyAll()通知Looper创建完了。
接下来:

  onLooperPrepared();
  Looper.loop();

最重要的是Looper.loop()这个方法,在Hander机制中我分析过,是不断的从MessageQueue中获取消息让后分发给指定的Handler。
Handler创建完后,需要和Handler绑定,这样才能消息处理,创建指定Looper的Handler:

        Handler mHandler = new Handler(handlerThread.getLooper(), new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                //实现自己的消息处理
                return true;
            }
        });

在HandlerThread创建成功后,通过getLooper就可以获得Looper对象,因此Handler,Looper,MessageQueue就完成了消息事件机制。

    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的差别了,HandlerThread在Thread的基础上添加了一个Looper+Handler,在有消息时分发消息处理,没有消息时阻塞式等待消息而不是退出。Thread在处理完耗时操作后就会退出线程。
IntentService借助HandlerThread来区别Service,在新的工作线程中来处理耗时任务,好处也就不言而喻了吧。

你可能感兴趣的:(Android IntentService源码分析)