Android中Java服务过程
1,ServiceManager的Java代理对象的获取过程
1.Client、Server和ServiceManager实现在用户空间中,Binder驱动程序实现在内核空间中
2.Binder驱动程序和ServiceManager在Android平台中已经实现,开发者只需要在用户空间实现自己的Client和Server
3.Binder驱动程序提供设备文件/dev/binder与用户空间交互,Client、Server和ServiceManager通过open和ioctl文件操作函数与Binder驱动程序进行通信
4.Client和Server之间的进程间通信通过Binder驱动程序间接实现
5.Service Manager是一个守护进程,用来管理Server,并向Client提供查询Server接口的能力
ServiceManager的Java代理对象的类型为ServiceManagerProxy,它实现了IServiceManager接口,
IServiceManager接口继承了IInterface接口,并定义了四个成员函数:getService,checkService,addService和listService。
ServiceManager的Java代理对象的内部有一个成员变量mRemote,类型为IBinder,实际上指的是一个BinderProxy对象。
2,Java服务接口的定义和解析
以IAudioService为例
publicinterface IAudioService extends android.os.IInterface
{
/**Local-side IPC implementation stub class. */
publicstatic abstract class Stub extends android.os.Binder implementsandroid.media.IAudioService
{
privatestatic final java.lang.String DESCRIPTOR ="android.media.IAudioService";
/**Construct the stub at attach it to the interface. */
publicStub()
{
this.attachInterface(this,DESCRIPTOR);
}
@Overridepublic boolean onTransact(int code, android.os.Parcel data,android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch(code)
{
caseINTERFACE_TRANSACTION:
}
}
***
privatestatic class Proxy implements android.media.IAudioService
{
privateandroid.os.IBinder mRemote;
Proxy(android.os.IBinderremote)
{
mRemote= remote;
}
}
}
}
}
文件定义了一个java接口IAudioService,一个Java抽象类IAudioService.Stub和一个Java类IAudioService.Stub.Proxy,而IAudioService.Stub是IAudioService内部类,IAudioService.Stub.Proxy是在IAudioService.Stub内部类
IAudioService.Stub类描述的是一个Java服务
IAudioService.Stub.Proxy类描述的是一个Java服务代理对象。
IAudioService.Stub.Proxy类内部有一个成员变量mRemote,他指向的是一个Java服务代理对象,即一个BinderProxy对象,用来向IAudioService接口的Java服务发送进程间通信请求。
3,Java服务的启动过程
Java服务一般是运行在Android系统进程System或者Android应用程序进程中的,他们在启动之前,需要将自己注册到ServiceManager中,以便Client进程可以通过ServiceManager来获得他们的Java服务代理对象。
ClassServerThread extends Thread{
¨¨¨
Publicvoid run(){
¨¨¨
try{
Slog.i(TAG,"Audio Service");
ServiceManager.addService(Context.AUDIO_SERVICE,new AudioService(context));
}catch (Throwable e) {
Slog.e(TAG,"Failure starting Audio Service", e);
}
¨¨¨
}
}
Android系统进程System启动时,会创建一个ServerThread线程来启动系统中的关键服务,AudioService在ServerThread线程中启动的。首先创建一个服务AudioService(context),然后调用ServiceManager类的静态成员函数addService将其注册到ServiceManager中。
4,java服务代理对象的获取过程
Java服务注册到ServiceManager中之后,Android应用程序就可以通过ServiceManager来获得他的一个Java服务代理对象了。
publicclass AudioManager {
privatestatic IAudioService sService;
privatestatic IAudioService getService()
{
if(sService != null) {
returnsService;
}
IBinderb = ServiceManager.getService(Context.AUDIO_SERVICE);
sService= IAudioService.Stub.asInterface(b);
returnsService;
}
}
通过ServiceManager类的静态成员函数getService来获得名称为Context.AUDIO_SERVICE的Java服务代理对象,接着再通过IAudioService.Stub.asInterface将这个服务代理对象封装成一个实现了IAudioService接口的Java服务代理对象。
5,Java服务的调用过程
First:首先在MovieView类中获得AudioManager类的对象mAudioManager,然后调用该类getStreamVolume函数。
publicclass MovieView extends Activity {
privateAudioManager mAudioManager = null;
mAudioManager= (AudioManager) getSystemService(Context.AUDIO_SERVICE);
currentVolume= mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
}
Activity继承ContextThemeWrapper,ContextThemeWrapper继承ContextWrapper,ContextWrapper继承Context,在类Context中getSystemService为抽象函数,ContextThemeWrapper类实现了该函数:
publicObject getSystemService(String name) {
if(LAYOUT_INFLATER_SERVICE.equals(name)) {
if(mInflater == null) {
mInflater= LayoutInflater.from(mBase).cloneInContext(this);
}
returnmInflater;
}
returnmBase.getSystemService(name);
}
变量mBase类型为Context,而ContextImpl继承Context并重写了getSystemService()函数。
publicObject getSystemService(String name) {
if(WINDOW_SERVICE.equals(name)) {
returnWindowManagerImpl.getDefault();
}else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
¨¨¨
}else if (AUDIO_SERVICE.equals(name)) {
returngetAudioManager();
¨¨¨
}
returnnull;
}
而函数getAudioManager实现如下,最后返回AudioManager类的对象。
privateAudioManager getAudioManager()
{
if(mAudioManager == null) {
mAudioManager= new AudioManager(this);
}
returnmAudioManager;
}
Second:AudioManager类中getStreamVolume函数如下,获得IAudioService的Java服务代理对象,然后调用代理对象即IAudioService.Stub.Proxy类中getStreamVolume函数。
publicclass AudioManager {
privatestatic IAudioService sService;
privatestatic IAudioService getService()
{
if(sService != null) {
returnsService;
}
IBinderb = ServiceManager.getService(Context.AUDIO_SERVICE);
sService= IAudioService.Stub.asInterface(b);
returnsService;
}
publicint getStreamVolume(int streamType) {
IAudioService service= getService();
try {
returnservice.getStreamVolume(streamType);
} catch(RemoteException e) {
Log.e(TAG, "Deadobject in getStreamVolume", e);
return 0;
}
}
}
Third:IAudioService.Stub.Proxy类如红色标识所示,mRemote变量类型为android.os.IBinder,而IAudioService.Stub继承了android.os.IBinder,并重写了函数onTransact,
IAudioService.Stub.Proxy类中getStreamVolume首先获取所要传输的数据,然后通过mRemote变量调用了IAudioService.Stub重写的函数onTransact。
在IAudioService.Stub类中首先通过获取传输过来的数据,然后调用了this.getStreamVolume(_arg0)。
publicinterface IAudioService extends android.os.IInterface
{
/**Local-side IPC implementation stub class. */
publicstatic abstract class Stub extends android.os.Binder implementsandroid.media.IAudioService
{
privatestatic final java.lang.String DESCRIPTOR ="android.media.IAudioService";
/**Construct the stub at attach it to the interface. */
publicStub()
{
this.attachInterface(this,DESCRIPTOR);
}
@Overridepublic boolean onTransact(int code, android.os.Parcel data,android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch(code)
{
caseTRANSACTION_getStreamVolume:
{
data.enforceInterface(DESCRIPTOR);
int_arg0;
_arg0= data.readInt();
int_result = this.getStreamVolume(_arg0);
reply.writeNoException();
reply.writeInt(_result);
returntrue;
}}
}
***
privatestatic class Proxy implements android.media.IAudioService
{
privateandroid.os.IBinder mRemote;
Proxy(android.os.IBinderremote)
{
mRemote= remote;
}
public int getStreamVolume(intstreamType) throws android.os.RemoteException
{
android.os.Parcel_data = android.os.Parcel.obtain();
android.os.Parcel_reply = android.os.Parcel.obtain();
int_result;
try{
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(streamType);
mRemote.transact(Stub.TRANSACTION_getStreamVolume,_data, _reply, 0);
_reply.readException();
_result= _reply.readInt();
}
finally{
_reply.recycle();
_data.recycle();
}
return_result;
}
}
}
}
}
Fourth:类AudioService继承了IAudioService.Stub,并重写了函数getStreamVolume,最后将获得的值返回给调用者。
publicclass AudioService extends IAudioService.Stub {
publicint getStreamVolume(int streamType) {
ensureValidStreamType(streamType);
return(mStreamStates[streamType].mIndex + 5) / 10;
}
}