【Android】Service知识点
启动方式
1、startService()启动
该方式启动的service可无限期运行下去,需调用stopSelf()或调用stopService()停止。当系统资源不足时,Android系统也可能结束服务。
2、bindService()启动:
该方法启动时,客户可通过IBinder接口与service进行通信,可通过unbindService()关闭连接。一个service可以同时与多个调用者绑定,当所有调用者都解除绑定后销毁service。
生命周期
1、startService()启动的生命周期
onCreate():初始化,只被调用一次;
onStartCommand():通过startService()启动服务时系统都会调用此方法,接受Intent数据;
onDestory():服务不再使用且被销毁,系统调用此方法;
2、bindService()启动的生命周期
onCreate():初始化,只被调用一次;
onBind():bindService()与服务绑定时调用该方法,返回一个IBinder接口让调用者与服务进行通信;
onUnbind():unbindService()解除绑定后执行;
绑定服务的生命周期
如果单纯是绑定服务,由Android系统控制生命周期;
如果实现了onStartCommand()回调方法,需通过stopSelf()或stopService()停止服务;
当系统调用onUnbind()方法时,如果服务已启动并接受绑定,并想在客户端下一次绑定到服务时接受obRebind()调用,onUnbind()方法返回true。onRebind()返回空值,客户端仍在onServiceConnected()回调中接受IBinder。
服务类型
1、本地服务
最普遍使用的Service。
1.1 继承Service;
1.2 重写onCreate(),onStartCommand(),onDestory(),onBind();
1.3 在AndroidManifest.xml中注册;
1.4 使用Context#startService()启动服务,Context#stopService()停止服务;
2、通信服务(案例)
可与Activity通信的服务。
2.1 继承Binder,添加方法;
2.2 Service#onBind()返回实例;
2.3 Activity中结合ServiceConnection使用bindService建立通讯关联;
3、前台服务(案例)
前台Service在下拉通知栏中,优先级较高,不会因为系统内存不足而被回收
在本地服务基础上,重写onCreate(),在方法中主动调用startForeground()变成前台服务。
注:
8.0使用Context#startForegroundService()后,应用需在5s内调用该服务的startForground()
9.0之后启动前台服务需要添加权限,
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
4、远程服务
远程Service是运行在独立进程的,服务常住后台不受Activity影响,一般用于系统级别服务。
远程Service与应用程序进行跨进程通讯需要使用AIDL,服务器端与客户端使用如下:
4.1 服务器端
4.1.1 定义AIDL,声明提供给客户端的接口;
4.1.2 Service中实现AIDL中定义方法;
4.1.3 AndroidMainfest.xml中注册服务声明为远程服务;
4.2 客户端
4.2.1 拷贝服务端AIDL文件夹到目录;
4.2.2 Stub.asInterface获取服务器Binder,调用提供的方法;
4.2.3 绑定远程Service,Intent中传服务端的服务名称和所在包名;
IntentService
IntentService继承Service,处理Intent的异步任务请求,客户端调用Context#startService()发送请求,启动Service在内部构建一个线程处理请求,处理结束后Service停止。
1、除非必要,否则不需要实现onBind(),默认的onBind()返回null;
2、不需要重写onStartCommand(),只需要重写onHandleIntent(),系统收到请求时会调用onHandleIntent();
3、onHandleIntent()同时只能处理一个Intent,队列处理Intent请求,所有请求处理完后结束Service;
源码分析
@Override
public void onCreate() {
super.onCreate();
//新建线程并启动
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
//获取线程Looper,自己管理工作队列
mServiceLooper = thread.getLooper();
//新建绑定Looper的Handler
mServiceHandler = new ServiceHandler(mServiceLooper);
}
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
//需要重写的抽象方法
onHandleIntent((Intent)msg.obj);
//执行完结束服务
stopSelf(msg.arg1);
}
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
//传递intent
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
//发送消息添加到消息队列
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public void onDestroy() {
//清除消息队列中消息
mServiceLooper.quit();
}
执行流程:
创建工作线程和Handler绑定 -> onStartCommand()传递inetnt插入到工作队列并逐个发送给onHandleIntent() -> onHandleIntent()依次处理所有Intent
适用场景:
可用与处理简单的顺序执行的后台耗时任务