美文网首页
Service的两种启动

Service的两种启动

作者: 兔斯基第2号 | 来源:发表于2018-08-03 11:25 被阅读0次

    1. 同时存在两种启动

    Snipaste_2018-08-03_11-01-42.png

    如果既startService又bindService(无论先后),那么点击stop是无法停止的(点击无反应)。
    只有unbind解除绑定后才能进行销毁:

    • 如果点击过stop,会unbind+destroy;


      先startService后bindService
      先bindService后startService
    • 如果没有点击过stop,此时只会unbind不会destroy。

    总之,两种启动都存在的话,要stop是要先unbind的。

    关于通过bindService启动的service,在unbindService后service是否继续运行的讨论
    有三种情况:如果直接使用服务,则没有必要进行绑定,但是如果要使用服务里面的方法,则要进行绑定。具体的启动情况有下:

    1. 当启动时,单独调用bindService方法,在unbindService后,会执行service的onUnbind,在执行onDestroy方法。
    2. 当启动时,先调用startService,再调用bindService方法后,在unbindService后,会执行service的onUnbind,不会执行onDestroy方法。除非你在执行stopService。
    3. 先调用startService,在调用stopService,会执行service的onDestroy方法。

    2. startService

    已经知道多次以start方式启动service,只会执行一次onCreate(),会调用多次onStartCommand()。
    多次startService,可以是多个Activity里start,多个intent。结果是onStartCommand()中的startId不同。

            //连续启动Service
            Intent intentOne = new Intent(this, TestOneService.class);
            startService(intentOne);
            Intent intentTwo = new Intent(this, TestOneService.class);
            startService(intentTwo);
            Intent intentThree = new Intent(this, TestOneService.class);
            startService(intentThree);
    

    3. bindService

    bindService启动服务特点:

    1. bindService启动的服务和调用者之间是典型的client-server模式。调用者是client,service则是server端。service只有一个,但绑定到service上面的client可以有一个或很多个。这里所提到的client指的是组件,比如某个Activity。
    2. client可以通过IBinder接口获取Service实例,从而实现在client端直接调用Service中的方法以实现灵活交互,这在通过startService方法启动中是无法实现的。
    3. bindService启动服务的生命周期与其绑定的client息息相关。当client销毁时,client会自动与Service解除绑定。当然,client也可以明确调用Context的unbindService()方法与Service解除绑定。当没有任何client与Service绑定时,Service会自行销毁。

    总结调用bindService之后发生的事情:
    1.client执行bindService()
    2.如果Service不存在,则Service执行onCreate(),onBind()
    3.client实例ServiceConnection执行onServiceConnected()方法

    总结调用unbindService之后发生的事情:
    1.client执行unbindService()
    2.client与Service解除绑定连接状态
    3.Service检测是否还有其他client与其连接,如果没有Service执行onUnbind()和onDestroy()

    4. 两种启动方式的区别

    BindService和Started Service都是Service,有什么地方不一样呢:

    1. Started Service中使用StartService()方法来进行方法的调用,调用者和服务之间没有联系,即使调用者退出了,服务依然在进行【onCreate()- >onStartCommand()->startService()->onDestroy()】,注意其中没有onStart(),主要是被onStartCommand()方法给取代了,onStart方法不推荐使用了。

    2. BindService中使用bindService()方法来绑定服务,调用者和绑定者绑在一起,调用者一旦退出服务也就终止了【onCreate()->onBind()->onUnbind()->onDestroy()】。(如果调用者被销毁,service会销毁)

    5. flag

    下面重点关注下onStartCommand(Intent intent, int flags, int startId)方法。

    其中参数flags默认情况下是0,对应的常量名为START_STICKY_COMPATIBILITY。startId是一个唯一的整型,用于表示此次Client执行startService(...)的请求请求标识,在多次startService(...)的情况下,呈现0,1,2....递增。另外,此函数具有一个int型的返回值,具体的可选值及含义如下:

    • START_NOT_STICKY:当Service因为内存不足而被系统kill后,接下来未来的某个时间内,即使系统内存足够可用,系统也不会尝试重新创建此Service。除非程序中Client明确再次调用startService(...)启动此Service。

    • START_STICKY:当Service因为内存不足而被系统kill后,接下来未来的某个时间内,当系统内存足够可用的情况下,系统将会尝试重新创建此Service,一旦创建成功后将回调onStartCommand(...)方法,但其中的Intent将是null,pendingintent除外。

    • START_REDELIVER_INTENT:与START_STICKY唯一不同的是,回调onStartCommand(...)方法时,其中的Intent将是非空,将是最后一次调用startService(...)中的intent。

    • START_STICKY_COMPATIBILITY:compatibility version of {@link #START_STICKY} that does not guarantee that {@link #onStartCommand} will be called again after being killed。此值一般不会使用,所以注意前面三种情形就好。

    以上的描述中,“当Service因为内存不足而被系统kill后”一定要非常注意,因为此函数的返回值设定只是针对此种情况才有意义的,换言之,当人为的kill掉Service进程,此函数返回值无论怎么设定,接下来未来的某个时间内,即使系统内存足够可用,Service也不会重启。

    参考:

    1. Android Service两种启动方式详解(总结版)
    2. 关于通过bindService启动的service,在unbindService后service是否继续运行的讨论
    3. Android中BindService方式使用的理解
    4. Android总结篇系列:Android Service

    相关文章

      网友评论

          本文标题:Service的两种启动

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