Android学习日记

Android日记之IntentService源码解析

2019-09-26  本文已影响0人  居居居居居居x

前言

ServiceIntent是Service和Handler两个合在一起进行再次封装的类,可以实现在Service里面直接进行异步的操作,因为如果是直接在Service进行耗时操作的话,是很容易造成ANR的,所以这时候我们就需要这个ServiceIntent这个类的,使用方法在我的Android日记之Service这篇文章中已经讲述了,这里就不在赘述。

IntentService源代码

package android.app;

import android.annotation.WorkerThread;
import android.annotation.Nullable;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;


public abstract class IntentService extends Service {
    
    
    private volatile Looper mServiceLooper;
    //实例化一个内部类ServiceHandler
    private volatile ServiceHandler mServiceHandler;
    private String mName;
    private boolean mRedelivery;
    
    
    //创建一个内部类来ServiceHandler继承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);
        }
    }

    //构造函数传入名称
    public IntentService(String name) {
        super();
        mName = name;
    }

   
    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        //这里创建了一个HandlerThread
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

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

   
    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }

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

   
    @WorkerThread
    protected abstract void onHandleIntent(@Nullable Intent intent);
}

IntentService的源码很短,通过观察发现,里面其实是对HandlerThread进行了再次的封装,首先我们也发现,它是一个抽象类,这就需要我们去继承他然后去进行使用,因为它是继承Service的,所以它的生命周期方法是相同的,我们接下来来就按着生命周期一步一步的来看。

onCreate()生命周期

@Override
public void onCreate() {
    super.onCreate();
    //这里创建了一个HandlerThread
    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
    thread.start();

    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
}

首先是onCreate()方法,这里首先创建了一个HandlerThread,参数为你自己指定的名称,接来来开启了一个带有轮询器Looper的线程,然后还创建了一个用来处理异步操作的Handler。

//ServiceHandler是一个内部类,继承了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);
    }
}

这样一来IntentService就可以通过轮询来进行异步的耗时任务的操作,这里有几个关注的点,从代码里看出,ServiceHandler用的Looper其实是ThreadHandler的Looper,而HandlerThread的Looper是子线程的轮询器,MessageQueue也是ThreadHandler的消息队列,也就是说ServiceHandler的handlerMessage()也是执行在子线程中的,不是运行在主线程上的。

onStartCommand()生命周期

@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
    onStart(intent, startId);
    return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}

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


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

@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent); 

这里先调用了onStart()的方法,通过ServiceHandler构建了一个Message,然后通过传进来的Intent和startId赋值到Message里面去,最后通过ServiceHandler将消息发送出去,最后被HandleMessage接收并通过onHandleIntent()进行处理,这个方法是一个抽象方法,由我们自己去写需要处理的逻辑来进行耗时的操作。
当执行完毕后就会执行stopSelf(),这时候服务就会自动停止了。stopSelf()有两种重载方法,一个可以接收参数的,另一种是不接收参数的,区别在于,如果有传参数的话,则会把所有子线程待处理的任务全部处理后才会停止服务,没有传的话,就是执行完整个任务就直接停止了,后面的待任务也就不处理了。

onBind()和onDestroy()

@Override
public void onDestroy() {
    mServiceLooper.quit();
}


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

onDestory()没什么好说的,停止服务的时候进行调用,然后退出这个Looper轮询器,主要讲一讲onBind()整个方法,源码这里返回的是null,意思就是Google是不建议通过绑定的方式去使用IntentService,因为如果执行要使用绑定的方法去使用Service的的话,那么onHandleIntent()就不会被回调了,因为它是在onStartCommand()里的,这样子使用的话就和普通的Service没什么区别了。

上一篇下一篇

猜你喜欢

热点阅读