执行步骤:
1、 建立一个android工程,来为其他应用提供服务。工程名:ipc-aidl-test
2、 编写一个AIDL文件来向客户端定义接口,aidl文件使用java语法,类似一个接口类,只不过后缀名为aidl而不是java接口类的.java文件。aidl文件须放在package 定义的包路径下(android.ipc.aidl.test)。Eclipse中的ADT插件会为你自动生成一个IMyAIDLService.java文件。此文件在gen/package目录下。也可以通过android提供的aidl命令将aidl文件生成相应的java文件
IMyAIDLService.aidl: package android.ipc.aidl.test; interface IMyAIDLService{ //注意这里的接口名称与文件IMyAIDLService.aidl的文件名是一致的 String sayHello(); }
package android.ipc.aidl.test; public interface IMyAIDLService extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements android.ipc.aidl.test.IMyAIDLService { private static final java.lang.String DESCRIPTOR = "android.ipc.aidl.test.IMyAIDLService"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an android.ipc.aidl.test.IMyAIDLService interface, * generating a proxy if needed. */ public static android.ipc.aidl.test.IMyAIDLService asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof android.ipc.aidl.test.IMyAIDLService))) { return ((android.ipc.aidl.test.IMyAIDLService)iin); } return new android.ipc.aidl.test.IMyAIDLService.Stub.Proxy(obj); } public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_sayHello: { data.enforceInterface(DESCRIPTOR); java.lang.String _result = this.sayHello(); reply.writeNoException(); reply.writeString(_result); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements android.ipc.aidl.test.IMyAIDLService { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } public java.lang.String sayHello() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); java.lang.String _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_sayHello, _data, _reply, 0); _reply.readException(); _result = _reply.readString(); } finally { _reply.recycle(); _data.recycle(); } return _result; } } static final int TRANSACTION_sayHello = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); } public java.lang.String sayHello() throws android.os.RemoteException;
3、 接下来穿件一个服务类来实现aidl的接口。创建MyService.java类, MyService 需是一个Service.
MyService.java
package android.ipc.aidl.test; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; public class MyService extends Service{ @Override public IBinder onBind(Intent arg0) { return new MyServiceImpl(); } public class MyServiceImpl extends IMyAIDLService.Stub{ public String sayHello() throws RemoteException { return " This is my aidl test sample!"; } } }
4、 然后在AndroidManifest.xml中注册Service.
<service android:name="android.ipc.aidl.test.MyService"> <intent-filter> <action android:name="android.ipc.aidl.test.IMyService" /> //通过过滤器来公开此服务,在其他应用即客户端中需要使用到的。 </intent-filter> </service>
5、 Ok 服务端完成。
接下来实现客户端部分,同样创建一个android工程。工程名:aidl-client
1、 将之前生产的IMyAIDLService.java文件复制到此工程下。这里需要创建一个与IMyAIDLService.aidl包相同的包,并将IMyAIDLService.java文件放在此包下。或者你也可以将上面所谓服务端的文件IMyAIDLService.java打成jar后添加在客户端应用中。具体要这步操作你懂得……
2、 下面说下客户端是怎么去调用的。下面的代码是这样实现的,在一个activity中去bind服务端提供的Service并且调用服务端是已经实现的sayHello方法。直接上代码。
布局代码:<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" tools:context=".ClientActivity" > <!--显示sayHello返回字符串用--> <TextView android:id="@+id/tv" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <!-- bindService--> <Button android:id="@+id/btn1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="BindAIDLService"/> <!—调用sayhello方法 --> <Button android:id="@+id/btn2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="SayHello"/> </LinearLayout>
主Activity
public class ClientActivity extends Activity implements OnClickListener{ private IMyAIDLService myService = null; private Button sayHello; private Button bindaidlService; private TextView textview; private ServiceConnection serviceConnection = new ServiceConnection() { public void onServiceDisconnected(ComponentName name) { } public void onServiceConnected(ComponentName name, IBinder service) { //获取服务对象 myService = IMyAIDLService.Stub.asInterface(service); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); bindaidlService = (Button)findViewById(R.id.btn2); sayHello = (Button)findViewById(R.id.btn1); textview = (TextView)findViewById(R.id.tv); bindaidlService.setOnClickListener(this); sayHello.setOnClickListener(this); } public void onClick(View v) { switch(v.getId()){ case R.id.btn1: //bind aidl服务 bindService(new Intent("android.ipc.aidl.test.IMyService"), serviceConnection, Context.BIND_AUTO_CREATE); break; case R.id.btn2: try { textview.setText(myService.sayHello()); } catch (RemoteException e) { e.printStackTrace(); } break; } } }