Service学习笔记01-启动方式与生命周期

0 系列汇总

1 Service的使用场景

Service 是一种可在后台执行长时间运行操作而不提供界面的应用组件,服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行。此外,组件可通过绑定到服务与之进行交互,甚至是执行了进程间通信(IPC)。
以下是三种不同不同的服务类型。

  • 前台
    前台服务执行一些用户能注意到的操作。例如,音频应用会使用前台服务来播放音频曲目。前台服务必须显示通知。即使用户停止与应用的交互,前台服务仍会继续运行。

  • 后台
    后台服务执行用户不会直接注意到的操作。例如,如果应用使用某个服务来压缩其存储空间,则此服务通常是后台服务

  • 绑定
    当应用组件通过调用bindService()绑定到服务时,服务处于绑定状态,绑定服务会提供C/S接口,以便组件与服务进行交互、发送请求、接收结果,甚至是利用进程间通信(IPC)跨进程执行这些操作。仅当与另一个应用组件绑定时,绑定服务才会运行。多个组件可同时绑定到服务,但是要全部取消绑定后,该服务即会被销毁。

2 Service的两种启动方式

无论是startService还是bindService都是通过Intent来显式指定,且不要为服务声明Intent 过滤器。使用隐式Intent启动服务存在安全隐患,因为您无法确定哪些服务会影响Intent,而用户也无法看到哪些服务已启动。从Android 5.0 (API 21)开始,如果使用隐式Intent调用bindService(),则系统会抛出异常。
Service 必须在AndroidManifest清单文件中定义,系统不会识别和运行任何未声明的服务。完整的可参考,android:name属于是唯一必需的属性,用于指定服务的类名。发布应用后,请确保此类名不变,以避免因依赖显式Intent来启动或者绑定服务不可用的风险
一个典型的Service 声明见如下所示:

<application
    <service
        android:name="com.hl.bindertest.service.LocalService"
        android:exported="false"
        android:process=":Daemon"/>
</application>
  • android:name
    实现服务的 Service 子类的名称。此名称应该是一个完全限定类名称,如(“com.example.project.RoomService”)。不过,作为一种简写形式,如果名称的第一个字符是句点,(如“.RoomService”),则会将其附加到 元素中指定的软件包名称(不建议采用此方式)。发布应用后,不能更改此名称(除非您已设置 android:exported=“false”),且修改后将应用调用处也同步修改。
  • android:process
    将运行服务的进程的名称。通常,应用的所有组件都会在为应用创建的默认进程中运行。它与应用软件包的名称相同。 元素的 process 属性可以为所有组件设置不同的默认值。即只有需要另起一个进程运行引服务时,通过以冒号(:)开头的名称指定一个新进程的名称,否则process属性不需要定义
  • android:exported
    如果为true,则表示其他应用的组件可以调用服务或者与之交互。建立如果明确不需要提供给其他三方应用使用,则务必将其置为false

2.1 通过startService()启动服务

startService 是不能与Service进行交互的,在调用startService启动服务后,与调用者就无关联了,服务会依次执行onCreate()onStartCommand()方法,直到被stopService()停止服务或者自身通过stopSelf()停止服务
调用方法所示所示:

    // 应用内可直接通过class文件指定要启动的Service
    Intent startIntent = new Intent(this, MyService.class);
    startService(startIntent);
    // 也可通过packageName和Service 全路径名称指定
    Intent intent = new Intent();
    intent.setClassName("com.hl.bindertest", "com.hl.bindertest.service.LocalService");
    startService(startIntent);

2.2 通过binService()绑定

    Intent startIntent = new Intent(this, MyService.class);
    startService(startIntent);
	
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "on ServiceDisConnected executor");

        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "on onServiceConnected executor");
            downloadBinder = (MyService.DownloadBinder) service;
        }
    };
	
	bindService(bindIntent, connection, BIND_AUTO_CREATE);
	
	// 在使用完成后,及时解绑服务
	unbindService(connection);

3 Service 的回调方法与生命周期

  • 说明:
  1. Service 是系统生成的天然的单例,如果onCreate() 方法只会执行一次,如果Service已经被启动,onCreate()不会再被调用
  2. 需要注意的是,Service的onCreate()onBind()等方法都是默认执行在主线程中的,也就是说,我们需要在服务的内部手动创建子线程,并在这里执行具体的任务,否则有可能出现ANR的问题
  3. startService()stopService()是成对出现的(当然也可通过stopSelf)()); bindService()和unBindService()也是成对出现的。在Service使用过程中要注意及时解绑和停止Service,严格控制Service的生命周期才能有效避免功耗和内存的问题

3.1 重要的回调方法说明

  • onCreate()
    **首次创建服务时,**系统会(在调用onStartCommand()或者onBind()之前)调用此方法来执行一次性设置程序。如果服务已经在运行,则不会调用此方法
  • onStartCommand()
    当其他组件通过startService的方式启动Service时,执行此方法时,服务即会启动并可在后台无限期运行。如果您实现此方法,则在服务工作完成后,您需要负责通过调用stopSelf()或者stopService来停止服务。(如果您只想提供绑定,则无需实现此方法
  • onBind()
    当另一个组件想要与服务(例如执行RPC)时,系统会通过调用bindService()来调用此方法。在此方法的实现中,您必须通过返回IBinder提供一个接口,以供客户端用来与服务进行通信。请务必实现此方法;但是,如果您并不希望允许绑定,则应返回null。
  • onDestory
    当不再使用服务且准备将其销毁时,系统会调用此方法。服务应通过实现此方法来清理任何资源,如线程、注册的侦听器、接收器等,这是服务接收的最后一个调用。

如果组件通过调用startService启动服务,则服务会一直运行,直到通过stopSelf()自行停止运行,或由其他服务通过调用stopService将其停止为止。

3.2生命周期

  1. Service是典型的单例模式,onCreate() 只会执行一次,已经启动后再次调用startServicebindService并不会再次执行onCreate()方法
3.2.1 只通过startService启动服务的生命周期

在这里插入图片描述

3.2.2 只通过bindService启动服务的生命周期

在这里插入图片描述

3.2.3 同时使用startService()启动服务、BindService()绑定服务的生命周期

需要同时解绑和停止服务才会最终执行onDestory()将服务销毁
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值