Service的使用相关总结

Service的生命周期

这里写图片描述

Service的分类

1、本地服务Local Service:

Local Service 用于应用程序内部。用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好

2、远程服务Remote Service:

Remote Service 用于android系统内部的应用程序之间。可以定义接口并把接口暴露出来,以便其他应用进行操作。可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。

Service的两种启动方式

1、startService方式(和stopService配对使用):

这种方式启动服务之后,调用者和服务就没有什么关系了,就算是退出当前的调用者,服务也不会关闭直到显式的调用stopService()或者stopSelf(),调用者和服务之间没有通信,这种方式服务的生命周期如下:

  • onCreate() : 创建服务,并初始化一些资源
  • onStartCommand() : 启动服务,值得说明的是服务中有onSart()方法,它是在android2.0一下的版本中使用。而在android2.0以上则使用onstartCommand()方法。它们两个方法放在一起使用时,不会产生冲突,同时每一次调用startService()都会调用onStartCommand()方法,但是实际上的每个服务都只会存在一个实例
  • onDestory() : 销毁服务,并做资源回收

2、bindService方式(和unBindService配对使用):

这种方式启动服务之后,服务和调用者之间产生紧密的联系,当调用者销毁之后,服务也随之销毁,而且两者之间可以自由的通信,其生命周期如下

  • onCreate() : 创建服务,并初始化一些资源
  • onBind() : 绑定服务,服务开始运行
  • onUnbind():取消绑定
  • onDestroy() :销毁服务,并做资源回收
bindService方式调用的流程图:

这里写图片描述

注意
1、使用bindService方法绑定服务时不会再走onStart()或者onStartCommand()方法,若是同时调用startService()和bindService()方法,那么在销毁的时候必须对应的执行stopService()和unBindService()方法才能销毁服务
2、ServiceConnection中的onServiceDisconnected()方法在正常情况下是不被调用的,它的调用时机是当Service服务被意外销毁时,例如内存的资源不足时

onStartCommand()方法返回值的探讨

  • START_STICKY(常量值:1):sticky的意思是“粘性的”。使用这个返回值时,我们启动的服务跟应用程序”粘”在一起,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务。当再次启动服务时,传入的第一个参数将为null;
  • START_NOT_STICKY(常量值:2):“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务
  • START_REDELIVER_INTENT(常量值:3):重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入

以上三种情况,可以理解为发生车祸后的人:

  • START_STICKY:(常量值:1)车祸后自己苏醒,但是失忆;
  • START_NOT_STICKY:(常量值:2)车祸后再也没有苏醒;
  • START_REDELIVER_INTENT:(常量值:3)车祸后自己苏醒,依然保持记忆。

关于IntentService

为什么要使用IntentService?

我们知道Service中的代码都是默认运行在UI线程中的,所以这里是不能直接处理一些耗时的逻辑,否则就容易出现ANR,这时候就需要使用Android多线程技术了,在每一个服务中的具体方法里开启一个子线程,在子线程中处理耗时的操作,如下所示:

 @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                //......耗时操作
                //处理完成之后,为防止服务一直运行,调用stopSelf方法
                stopSelf();
            }
        }).start();
        return super.onStartCommand(intent, flags, startId);
    }

但是我们很容易忘记开线程或者是调用stopSelf()方法,因此可以使用Android中提供的IntentService类,用法如下:

public class MyIntentService extends IntentService {

    //提供无参构造,必须调用父类的构造方法
    public MyIntentService() {
        super("MyIntentService");
    }

    //子类实现onHandleIntent,此方法运行在子线程中
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        //逻辑操作
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //销毁服务,回收资源
    }
}
IntentService与activity的通信方式

使用Service和activity通信,其方式有两种,其一是使用绑定Binder的方式,其二是使用广播的方式,在IntentService中固然可以使用bindService开启服务,采用绑定Binder对象,但是这种方式不会执行onHandleIntent方法,我们知道IntentService是继承Service的一个抽象类,则使用bindService方式其实是和使用Service是一样的,这就失去了IntentService的意义了,因此可以采用第二种方式,就是广播的方式。我们从IntentService的源码就可以看到IntentService是不支持bindService这种方式的

  /**
     IntentService中没有继承Binder的类,并且onBind方法中返回值为“null”
  */
  @Override
    @Nullable
    public IBinder onBind(Intent intent) {
        return null;
    }

  /**
     采用startService会执行onStart方法,我们可以看到IntentService中有定义的Hander对象,发送消息
  */
   @Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

 /**
    handleMessage方法中处理消息,之后执行stopSelf,这就是IntentService任务执行完成之后,
    自动结束服务的原理
 */   
 @Override
  public void handleMessage(Message msg) {
       onHandleIntent((Intent)msg.obj);
       stopSelf(msg.arg1);
   }

猜你喜欢

转载自blog.csdn.net/qq_33768280/article/details/80413420