Android组件---Service
1.定义、作用及特点
服务,Android四大组件之一,属于计算型组件。
提供需要在后台长期运行的服务,如复杂计算、音乐播放、下载等
无界面,后台运行,生命周期长
2.生命周期
方式一:startService
Service启动--->onCreate--->onStartCommand--->Service running--->onDestory--->Service终止
方式二:
Service绑定--->onCreate--->onBind--->Clients are bound to service--->onUnbind--->onDestory--->Service终止
startService:启动服务
stopService:关闭服务
bindService:绑定服务
unbindService:解绑服务
onCreate:创建服务
onStartCommand:开始服务
onDestory:销毁服务
onBind:绑定服务
onUnbind:解绑服务
3.服务的类型
3.1 按照运行地点分类
| 类别 | 特点 | 优点 | 缺点 | 应用场景 |
|---|
| 本地服务(LocalService) | 运行在主线程,主线程终止后,服务也会被终止 | 节约资源;通信方便,由于在同一进程,因此不需要IPC和AIDL | 限制性大(主进程被终止后,服务也会被终止) | 需要依附于某个进程(最常用的服务,如音乐播放) |
| 远程服务(RemoteService) | 运行在独立进程;服务常驻在后台,不受其它Activity影响 | 灵活:服务常驻在后台,不收其它Activity影响 | 消耗资源:单独进程;使用AIDL进行IPC复杂 | 系统级别服务 |
3.2 按照运行类型分类
| 类别 | 特点 | 应用场景 |
|---|
| 前台服务 | 在通知栏显示通知(用户可看到) | 服务使用时,需让用户知道&进行相关的操作,如音乐播放服务; (服务终止时,通知栏的通知也会消失) |
| 后台服务 | 处于后台的通知(用户无法看到) | 服务使用时不需要让用户知道%进行相关操作,如天气预报、日期同步 (服务被终止时,用户无法知道) |
3.3 按照功能分类
| 类别 | 特点 | 应用场景 |
|---|
| 不可通信的后台服务 | 用startService启动,退出者退出后Service仍然存在 | 服务不需要与Activity&Service通信 |
| 可通信的后台服务 | 用bindService启动,调用者退出后,随调用者销毁 | 服务需要与Activity&Service通信,需控制服务开启时刻 |
| 可通信的后台服务(同上) | 使用startService、bindService启动,调用者退出后,随着调用者销毁 | 需要与Activity&Service通信,不需要控制服务开始时刻,(服务一开始遍运行) |
4.本地Service
简介:本地Service是最普通、最常用的后台服务Service.
使用步骤:
1.自定义Service继承自Service,重写对应的生命周期方法(onCreate、onStartCommand、onDestory、onBind)
2.构建用于启动服务的intent对象
3.调用startService启动Service,调用stopService停止服务
4.在AndroidManifest文件中注册Service
5.Service的常用属性
| 属性 | 说明 | 备注 |
|---|
| android:name | Service的类名 | |
| android:label | Service的名字 | 若不设置,则默认Service的类名 |
| android:icon | Service的图标 | |
| android:permission | 申明此Service的权限 | 有提供该权限的应用才能控制或连接此服务 |
| android:process | 表示该服务是否在另一个进程中运行(远程服务) | 不设置则默认本地服务;remote则默认成远程服务 |
| android:enable | 系统默认启动 | true:Service会默认被系统启动;不设置则默认为false |
| android:exported | 该服务是否能够被其它应用程序所控制或连接 | 不设置默认此项为false |
6.可通信的服务Service
在本地Service的基础上,增加了与Activity通信的功能,即使用绑定Service服务
步骤如下:
1.在新建子类继承Service类,并新建一个子类继承自Binder类,写入与Activity关联所需要的方法,创建实例
MyService extends Service{
onCreate、onStartCommand、onDestory、onBind、onUnbind
class MyBinder extends Binder {
public void service_connect_activity{}
}
}
2.在主布局文件中增加bind与unbind按钮,分别进行bindService和unBindService操作
3.在Activity通过调用MyBinder类中的public方法来实现Activity与Service的联系
即:实现了Activity指挥Service干什么,Service就去干什么的功能
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder = (MyService.MyBinder) service;
myBinder.service_connect_Activity();
}
case R.id.bindService:
Intent bindIntent = new Intent(this, MyService.class);
bindService(bindIntent,connection,BIND_AUTO_CREATE);
break;
case R.id.unbindService:
unbindService(connection);
break;
7.前台Service
前台Service在下拉通知栏有显示通知,但后台Service没有;
前台服务的优先级比较高,不会由于系统内存不足而被回收;
后台服务优先级较低,当系统出现内存不足情况时,很有可能会被回收。
@Override
public void onCreate() {
super.onCreate();
System.out.println("执行了onCreat()");
Intent notificationIntent = new Intent(this,MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0);
Notification.Builder builer = new Notification.Builder(this);
builer.setContentTitle("前台服务通知的标题");
builer.setContentText("前台服务通知的内容");
builer.setSmallIcon(R.mipmap.ic_launcher);
builer.setContentIntent(pendingIntent);
Notification notification = builer.getNotification();
startForeground(1, notification);
}
8.远程Service
https:
9.Service与Thread的区别
Service与Thread无任何关系
后台:后台任务完全不依赖UI,即使Activity被销毁,程序被关闭,只要进程还在,后台任务就可继续运行
| 类型 | 相同点 | 不同点 | |
|---|
| 作用 | 运行线程 | 运行范围 |
| Service | 执行异步操作 | 主线程 | 进程: 完全不依赖UI/Activity,只要进程还在,Service就可继续运行; 所有Activity都可以与Service关联,并获取binder实例 & 操作其中的方法 若要处理耗时操作,则在Service里创建Thread子线程执行 |
| Thread | 执行异步操作 | 工作线程 | Activity 依赖与某个Activity 在一个Activity中创建的子线程,另一个Activity无法对其进行操作 Activity很难控制Thread 当Activity被销毁后,都无法再获取到之前创建的子线程实例 |
一般情况下,Service和Thread会联合一起使用,即在Service中再创建一个线程(工作线程),去处理耗时操作逻辑,如下代码:
方式1:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
@Override
public void run() {
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
方式2:
class MyBinder extends Binder {
public void service_connect_Activity() {
new Thread(new Runnable() {
@Override
public void run() {
}
}).start();
}
10.Service、IntentService及其他线程的区别
Service和IntentService的区别
| 类型 | 运行线程 | 结束服务 操作 | 备注 |
|---|
| IntentService(继承自Service) | 创建一个工作线程处理多线程任务 | 不需要 在所有Activity被处理完后,系统会自动关闭服务 | 1.IntentService为Service的onBind方法提供了默认实现:返回null 2.IntentService为Service的onStartCommand方法提供了默认实现,将请求的intent添加到队列 |
| Service | 主线程(不能处理耗时操作,否则会出现ANR) | 需要主动调用stopService | |
IntentService和其他线程的区别
| 类型 | 线程属性 | 作用 | 线程优先级 |
|---|
| IntentService | 类似于后台线程(采用HandlerThread实现) | 后台服务(继承了Service) | 高 (不容易被系统杀死) |
| 其他线程 | 普通线程 | 普通多线程任务 | 低 (如进程中无活动的四大组件,则该线程的优先级非常低,容易被系统杀死) |