【Android】Service启动、远程服务AIDL、IntentService

启动方式

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、远程服务

服务端AIDL客户端

远程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

适用场景:

可用与处理简单的顺序执行的后台耗时任务

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值