美文网首页
Android四大组件——Service

Android四大组件——Service

作者: Samuel_Tom | 来源:发表于2018-09-01 13:18 被阅读0次

    Service是可以长时间运行在后台的没有用户界面的组件(区别于Activity),运行与UI线程中(区别与Thread)。

    1、Service的两种启动方式

    (1)startService()

        创建服务类继承于Service,onBind()方法默认返回null就行;

        在AndroidManifest文件中配置Service组件;

        指定Intent并通过Context.startService(intent)方法启动Service服务;

        在需要停止服务的时候通过Context.stopService(intent);

    (2)bindService()

        创建BindService服务端继承于Service,创建一个实现IBinder接口的实例对象并提供公共方法给客户端调用;

        在服务端中必须实现onBind()回调方法并返回创建的Binder对象实例;

        在客户端中实现,从onServiceConnected(ComponentName name, IBinder binder)回调方法中获取Service端Binder实例,并使用提供的方法调用服务端Service;

        client通过bindService (Intent service, ServiceConnection sc, int flags)方法将Service绑定到此Client上;

        当Client在恰当的生命周期(如onDestroy等)时,此时需要解绑之前已经绑定的Service,通过调用函数unbindService(ServiceConnection sc);

    2、Service的生命周期

        (1)通过startService方式启动

                首次调用startService()时,依次回调 onCreate()、onStartCommand();

                再次调用startService()时,将只执行onStartCommand(),因为此时Service已经创建了,无需执行onCreate()回调。

                调用stopService()或者stopSelf()时,回调onDestroy();

    PS:所以无论多少次调用startService,每个服务都只存在一个实例,只需要一次stopService()或stopSelf()即可将此Service终止,然后执行onDestroy()函数。

                与client调用组件的关系(Activity):通过startService方式启动的服务的生命周期与Activity的生命周期没有任何关系,Activity如果销毁了也不会杀死Service,只有当Activity调用stopService或者Service本身调用stopSelf()才能停止此服务。(系统内存不足时也会kill掉Service)

        (2)通过bindService方式启动

                首次进行bindService()绑定时,依次回调onCreate()、onBind()、onServiceConnected();

                再次进行bindService()绑定时,没有触发回调;

                调用unBindService()进行解绑时,依次回调onUnBind()、onDestroy();

                与client调用组件的关系(Activity):通过bindService方式启动的服务的生命周期与Activity的生命周期有关系,只有当Activity被销毁了或者调用Context.unbindService才能停止Service服务,否则将一直在后台运行。(系统内存不足时也会kill掉Service)

    3、Service与Activity的通信方式

        (1)startService方式启动

                当通过startService(Intent intent)方式启动的Service,Activity可以把Intent参数传递给Service,如果此时Service需要把Intent参数传递给Activity,只能通过发送广播的形式(Activity需要注册广播)

        (2)bindService方式启动

                可以通过Binder对象(统一进程)或者Messenger信使(跨进程)进行通信。

    PS:关于onBind()的说明:onBind()是Service类中唯一的抽象方法,必须由子类实现,其返回值只对通过bindService方式启动的Service才有用,在startService方式中默认返回null就行。

    PS:onStartCommand(Intent intent, int flags, int startId)的参数说明:flags参数默认下为0,可以指定以下常量:

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

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

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

    PS:只有调用stopService才会回调onDestroy()方法。只有调用unbindService()才会回调onDestroy()方法。

    PS:在bindService启动方式中,客户端的onServiceDisconnected()不会在onUnBind()执行后回调,只有放系统异常杀死Service时才会进行回调。

    PS:BroadcastReceiver组件不能作为bindService()的client,因为BroadcastReceiver的生命周期很短,当执行完onReceive()回调时,BroadcastReceiver生命周期已经完结。而bindService又与Client本身的生命周期相关,因此Android中不允许BroadcastReceiver去bindService()。

    补充:
    因为Service运行在主线程,所以如果想要在Service执行耗时操作,必须创建子线程来执行耗时任务,但是由于Service服务需要手动调用stopService()去停止服务,操作起来比较麻烦,所以系统提供了IntentService来解决这个问题。IntentService继承于Service,同时封装了Handler和HandlerThread,重写onHandlerIntent()方法并在其中执行耗时任务即可,并且任务执行完毕后会自动调用stopSelf()停止服务,适用于完成一些短期的耗时任务。

    相关文章

      网友评论

          本文标题:Android四大组件——Service

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