Android面向面试复习----IntentService详解

时间:2021-01-18 04:37:51

IntentService详解(附个推IntentService示例)

1. 什么是IntentService?

  • IntentService继承Service,内部创建了HandlerThread和异步线程的Handler来进行耗时操作
  • 启动方式和Service一样
  • 在开启IntentService时,会回调执行onHandleIntent方法(异步线程中执行,非UI线程)
  • 执行完成后会自动停止,不需要额外调用stopSelf()。
  • 可以多次启动IntentService,不会有多个实例,只会多次回调onHandleIntent方法。

2. IntentService的使用方法

  1. 继承IntentService,复写构造方法和onHandleIntent方法

    public class MyIntentService extends IntentService{
    /**
    * Creates an IntentService. Invoked by your subclass's constructor.
    *
    * @param name Used to name the worker thread, important only for debugging.
    */
    public MyIntentService(String name) {
    super(name);
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
    int arg = intent.getIntExtra("arg", 0);
    switch(arg){
    case 1:
    //第一种情况处理
    break;
    case 2:
    //第二种情况处理
    break;
    case 0:
    //第三种情况处理
    break;
    }
    }
    }
  2. 在manifest文件中注册IntentService

    <service android:name=".intentservice.MyIntentService">
    </service>
  3. 通过startService启动IntentService

    Intent i = new Intent(this,MyIntentService.class);
    i.putExtra("arg",2);
    startService(i);
  4. 借鉴一下个推的IntentService的onHandleIntent相关方法

    在onHandleIntent中处理各种不同的情况,然后使用工厂方法模式,让子类实现那些未实现的接口,来执行不同的操作:接收消息的处理、设备是否在线的回调等。

        protected void onHandleIntent(Intent var1) {
    if(var1 != null) {
    try {
    this.processOnHandleIntent(var1);
    } catch (Throwable var3) {
    a.b("GTIntentService|" + var3.toString());
    }

    }
    }

    private void processOnHandleIntent(Intent var1) {
    Bundle var2 = var1.getExtras();
    if(var2 != null && var2.get("action") != null && var2.get("action") instanceof Integer) {
    switch(var2.getInt("action")) {
    case 10001:
    this.onReceiveMessageData(this, (GTTransmitMessage)var1.getSerializableExtra("transmit_data"));
    break;
    case 10002:
    this.onReceiveClientId(this, var2.getString("clientid"));
    case 10003:
    case 10004:
    case 10005:
    case 10006:
    case 10009:
    default:
    break;
    case 10007:
    this.onReceiveOnlineState(this, var2.getBoolean("onlineState"));
    break;
    case 10008:
    this.onReceiveServicePid(this, var2.getInt("pid"));
    break;
    case 10010:
    this.onReceiveCommandResult(this, (GTCmdMessage)var1.getSerializableExtra("cmd_msg"));
    }

    }
    }

3. IntentService源码解析

  1. onStart方法

    这里是标准的HandlerThread的标准用法,先创建HandlerThread实例,调用start()开启线程。使用HandlerThread中的looper绑定工作线程的Handler。

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

    }

  2. onStart

    在onStart中,调用工作线程的Handler发送消息到消息队列。

    public void onStart(@Nullable Intent intent, int startId) {
    Message msg = mServiceHandler.obtainMessage();
    msg.arg1 = startId;
    msg.obj = intent;
    mServiceHandler.sendMessage(msg);
    }
  3. 工作线程的Handler

    工作线程的Handler中调用了onHandleIntent方法,onHandleIntent由子类实现,执行耗时操作。最后再执行stopSelf(msg.arg1),此处表示,把消息队列中的消息处理完成后再停止。

    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);
    }
    }
  4. onBind

    不能通过onBindService的方式启动IntentService,回调不到onHandleIntent

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

4. 几种异步框架对比

IntentService: 进程优先级高,属于后台服务
其他异步线程需要绑定前台线程,进程优先级低。