在Android项目的实际开发中,或多或少的都要用到Service,比如监测APP升级、即时消息通知以及一些需要持久运行或耗时的操作,作为Android四大组件之一,Service的用法是必要掌握的,Service分为本地服务和远程服务,又可分为前台服务和后台服务,在service中,本地服务(LocalService)为普通服务,与客户端捆绑在一起,主进程停止后服务也会终止,无法独立存活,不过它节省资源,通信方便,通常可用于监测APP升级、音乐播放等;而远程服务(RemoteService)是一个独立的进程,可以独立存活,亦可以被其他不同包名的APP所共同调用,当然啦,由于是独立进程,相对来说更耗费资源,通讯也相对麻烦,既然是一个独立的进程,那么进程之间通信肯定就会用到AIDL。
今天探讨一下关于远程服务的实现及与客户端之间的通讯。
生命周期
先看一张图
这张图把生命周期分为两种情况,即开启服务startService()和绑定服务bindService(),startService()开启服务之后需要通过stopService进行停止,bindService()绑定服务之后则需要通过onUnbind()进行解绑停止,其实即便是通过开启服务的方式启动远程服务,也是可以随时被允许绑定,即startService()之后依然可以执行bindService(),那么交叉式生命周期见下图
实例讲解
远程服务如果想跟客户端通信,由于不在同一进程,就必须要用到Android接口定义语言,即AIDL(Android Interface Definition Language),关于AIDL的内容,网上很多详细讲解,我就不班门弄斧了。
首先创建一个.aidl文件,AndroidStudio可以直接创建,eclipse的话,创建一个File,后缀加上“.aidl”就可以了
这个文件里根据自身需要实现用于通讯的接口
package com.demo.service;
interface IRemoteService{
void setName(String name);
String getName();
}
然后创建一个服务类RemoteService,继承于Service,在这其中创建一个嵌套类ServiceImpl ,用于通信过程中的逻辑操作,与aidl中的接口对应,继承于Sub
class ServiceImpl extends Stub {
private String _name;
@Override
public void setName(String name) throws RemoteException {
_name = name;
}
@Override
public String getName() throws RemoteException {
return _name;
}
}
接着将ServiceImpl做一个简单的单例模式
// 将ServiceImpl做一个简单的单例模式
private ServiceImpl getInstance() {
if (serviceImpl == null) {
serviceImpl = new ServiceImpl();
}
return serviceImpl;
}
这样的话,就可以在生命周期 onBind()方法中将这个单例模式返回
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method