背景

Activity组件的学习就先告一段落,今天学习的内容是Service相关知识。

Service是什么?

Service翻译过来就是服务,是Android四大组件之一,属于计算型组件

Service提供需要在后台长期运行的服务,类似于复杂计算、音乐播放、下载、文件读写等

特点

  • 没有用户界面、在后台运行、生命周期长。
  • Service是运行在后台执行长时间运行的操作组件,它不提供任何用户界面,而作为与Activity同级的组件,它是运行在主线程中的(由于是在主线程,所以需要开一个线程开执行耗时操作)。
  • 一个组件还可以与一个Service进行绑定来实现组件之间的交互,甚至可以执行IPC(Inter-Process Communication)进程间通信。

生命周期

生命周期常用方法

手动调用方法

  • 启动服务 startService()

  • 关闭服务 stopService()

  • 绑定服务 bindService()

  • 解绑服务 unbindService()

内部自动调用方法

  • 创建服务 onCreate()
  • 开始服务 onStartCommand()
  • 销毁服务 onDestory()
  • 绑定服务 onBind()
  • 解绑服务 onUnbind()

应用场景

启动服务—>只能使用startService()

绑定服务—>只能使用bindService

启动服务后绑定—>startService()+bindService()

注意

startService()、stopService()只能开启&关闭Service,无法操作Service。

bindService()、unbindService()除了绑定&解除Service之后还能操作Service。

startService()开启的Service,绑定者退出之后Service仍然存在。

bindService()开启的Service,绑定者退出后Service随着调用者退出而销毁。

Service分类

  • 运行地点分类:本地服务,远程服务
  • 运行类型分类:前台服务,后台服务
  • 功能分类:可通信服务,不可通信服务

在去了解这些分类之前,我们先了解两个专业词语

ICP:Inter-Process Communication 即跨进程通信。

AIDL:Android Interface Definition Language,即Android接口定义语言,用于让某个Service与多个应用程序组件之间跨进程通信,从而实现多个应用程序共享同一个Service的功能。

一、本地服务**

特点

  • 运行在主线程。
  • 主线程被终止后,服务也会被中止。
  • 节约资源,不需要AIDL/IPC,简便。

场景

  • 最常用的是需要依附于某个进程,不需要常驻的服务,如音乐播放。

使用

步骤一:新建子类继承Service类,需要重写父类的onCreate()、onStartCommand()、onDestory()、onBind()。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MyService extends Service {
@Override
public void onCreate() {
super.onCreate();
System.out.println("执行了onCreat()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("执行了onStartCommand()");
return super.onStartCommand(intent, flags, startId);


}
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("执行了onDestory()");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}

步骤二:构建用于启动Service的Intent对象

步骤三:调用startService()启动服务,调用stopService停止服务

1
2
3
4
5
6
7
8
9
//构建启动服务的Intent对象
Intent startIntent = new Intent(this, MyService.class);
//调用startService()方法-传入Intent对象,以此启动服务
startService(startIntent);

//构建停止服务的Intent对象
Intent stopIntent = new Intent(this, MyService.class);
//调用stopService()方法-传入Intent对象,以此停止服务
stopService(stopIntent);

步骤四:在AndroidManifest.xml中注册Service

1
2
3
4
<application
//注册Service服务
<service android:name=".MyService"></service>
</application>

二、远程服务

特点

  • 运行在独立进程(占用一定资源)。
  • 服务常驻后台,不受其他Activity影响(Activity所在进程被kill时,服务仍在进行)
  • 使用AIDL进行IPC

场景

  • 系统级别服务(常驻),多个应用程序共享同一个后台服务(跨进程通信)

三、前台服务

特点

  • 在通知栏显示通知(用户可以看见)。

场景

  • 服务使用时需要让用户知道并进行相关操作,如音乐播放服务。
  • 服务被终止时,通知栏的通知也会消失。

使用

Service类onCreate()增加通知栏显示功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//添加下列代码将后台Service变成前台Service
//构建"点击通知后打开MainActivity"的Intent对象
Intent notificationIntent = new Intent(this,MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0);

//新建Builer对象
Notification.Builder builer = new Notification.Builder(this);
builer.setContentTitle("前台服务通知的标题");//设置通知的标题
builer.setContentText("前台服务通知的内容");//设置通知的内容
builer.setSmallIcon(R.mipmap.ic_launcher);//设置通知的图标
builer.setContentIntent(pendingIntent);//设置点击通知后的操作

Notification notification = builer.getNotification();//将Builder对象转变成普通的notification
startForeground(1, notification);//让Service变成前台Service,并在系统的状态栏显示出来

四、后台服务

特点

  • 处于后台的服务(用户无法看见)。
  • 后台任务运行完全不依赖于UI,即使Activity被销毁或者程序被关闭,主要进程还在,后台任务就可以继续运行。

场景

  • 服务使用时不需要让用户知道并进行相关的操作,例如天气更新、日期同步。

五、可通信服务

特点

  • 用bindService启动
  • 调用者退出后,随调用者销毁。
  • 只有绑定Service服务(Binder类、bindService()、onBind()、unbindService()、onUnbind())才能与Activity通信。

场景

  • 后台服务需要与Activity进行通信

六、不可通信服务

特点

  • 用startService启动
  • 调用者退出后,随调用者销毁

场景

  • 后台服务不进行任何通信。

AndroidManifest.xml中Service元素常见属性

  • android:name: 服务类名。可以是完整的包名+类名。也可使用. 代替包名。
  • android:exported: 其他应用能否访问该服务,如果不能,则只有本应用或有相同用户ID的应用能访问。默认为false。
  • android:process: 服务所运行的进程名。默认是在当前进程下运行,与包名一致。
  • android:permission: 申请使用该服务的权限,如果没有配置下相关权限,服务将不执行