编写android服务

来源:互联网 发布:弘付数据科技有限公司 编辑:程序博客网 时间:2024/05/16 08:42


服务(Service)是Android的四大组件之一,它利用底层Binder机制,实现了RPC机制。 一个服务即可以存在于一个独立的进程,也可以依附于已存在的某个进程中。服务可被同一进程中的Activity调用,也可以被位于不同进程中的某个Activity调用。 本文主要探讨怎样编写一个远程服务接口的过程。为演示作用,本文不介绍通过AIDL语言自动生成服务接口代码的过程。

首先,我们定义接口:

public interface IRemoteService extends IInterface {/** *  serviceMethod */ public void serviceMethod(int arg0, float arg1, long arg2, boolean arg3, double arg4, String arg5) throws RemoteException;}

需要说明的是,由于受Binder机制的约束,除基本数据类型外,对于自定义的数据类型,必须实现Parceable接口,才能作为服务方法的参数。本文将不考虑自定义类型作为参数传递的情况。

接下来的重点就是实现上述定义的服务接口,这里,为了支持同一进程和不同进程的Activity都能够调用该服务接口,我们需要两个接口实现,一个是本地实现,一个是远程实现。在介绍这两个实现代码之前,我们先看下对应的RemoteService类的实现:

public RemoteService extends Service {    @Overridepublic void onCreate() {}@Overridepublic void onDestroy() {        }@Overridepublic IBinder onBind(Intent intent) {// Select the interface to return.  If your service only implements// a single interface, you can just return it here without checking// the Intent.if (IRemoteService.class.getName().equals(intent.getAction())) {return mBinder;}return null;}/** * The IRemoteInterface is defined through IDL */private final RemoteServiceStub mBinder = new RemoteServiceStub() {public void serviceMethod(int arg0, float arg1, long arg2, boolean arg3, double arg4, String arg5) {//do something here}};}

在Android App开发中,定义自己的服务需要从Service类中派生,启动一个Service可以通过startService,也可以通过bindService, 对于通过bindService调用一个服务接口的方式,同时需要实现onBind()方法,它返回的IBinder对应就是我们下面将要介绍的服务实现类。

首先是本地接口实现类,代码如下:

/** Local-side IPC implementation stub class. */public abstract class RemoteServiceStub extends Binder implementsIRemoteService {private static final String DESCRIPTOR = "com.fyj.test.IRemoteService";/** Construct the stub at attach it to the interface. */public RemoteServiceStub() {this.attachInterface(this, DESCRIPTOR);}/** * Cast an IBinder object into an * com.fyj.test.IRemoteService interface, generating a * proxy if needed. */public static IRemoteService asInterface(IBinder obj) {if ((obj == null)) {return null;}IInterface iin = (android.os.IInterface) obj.queryLocalInterface(DESCRIPTOR);if (((iin != null) && (iin instanceof IRemoteService))) {return ((IRemoteService) iin);}return new RemoteServiceProxy(obj);}public IBinder asBinder() {return this;}@Overridepublic boolean onTransact(int code, Parcel data, Parcel reply, int flags)throws RemoteException {switch (code) {case INTERFACE_TRANSACTION: {reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_methodService: {data.enforceInterface(DESCRIPTOR);int _arg0;_arg0 = data.readInt();float _arg1;_arg1 = data.readFloat();long _arg2;_arg2 = (0!=data.readLong());boolean _arg3;_arg3 = data.readInt()?true:false;double _arg4;_arg4 = data.readDouble();String _arg5;_arg5 = data.readString();this.serviceMethod(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);reply.writeNoException();return true;}}return super.onTransact(code, data, reply, flags);} public void serviceMethod(int arg0, float arg1, long arg2, boolean arg3, double arg4, String arg5) throws RemoteException;static final int TRANSACTION_methodService = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);}

它实现为一个抽象类,将接口的具体实现延迟到RemoteService中去实现。在本类 中,主要实现了onTransact()方法,它将处理客户的调用请求。asInterface()接口将自动判断当前是本地调用还是远程调用,如果是远程调用,将使用 RemoteServiceProxy类的实例的接口调用服务,它的实现代码如下:

/** Local-side IPC implementation stub class. */public class RemoteServiceProxy implements IRemoteService {private static final String DESCRIPTOR = "com.fyj.test.IRemoteService";private IBinder mRemote;RemoteServiceProxy(IBinder remote) {mRemote = remote;}public IBinder asBinder() {return mRemote;}public String getInterfaceDescriptor() {return DESCRIPTOR;} public void serviceMethod(int arg0, float arg1, long arg2, boolean arg3, double arg4, String arg5) throws RemoteException {Parcel _data = Parcel.obtain();Parcel _reply = Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(anInt);_data.writeFloat(aFloat);_data.writeLong(aLong);_data.writeInt(((aBoolean)?(1):(0)));_data.writeDouble(aDouble);_data.writeString(aString);mRemote.transact(TRANSACTION_methodService, _data, _reply, 0);_reply.readException();}finally {_reply.recycle();_data.recycle();} }static final int TRANSACTION_methodService = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);}

该类是代理类,对服务的调用者是透明的。


在调用bindService的过程中,需要传递一个ServiceConnection对象,该对象将在服务连接成功后,会接收到服务类的对象,以此可以判断当前应该使用本地服务类实现,还是远程服务类实现,关于具体的实现细节,将另外专题分析。 下面给出ServiceConnection对象实现创建的代码:

private ServiceConnection mConnection = new ServiceConnection() {public void onServiceConnected(ComponentName className, IBinder service) {// TODO Auto-generated method stubmService = RemoteServiceStub.asInterface(service);...}public void onServiceDisconnected(ComponentName className) {// TODO Auto-generated method stubmService = null;...}};





0 0