AIDL的意义及用法

来源:互联网 发布:淘宝店铺怎么经营模式 编辑:程序博客网 时间:2024/05/22 01:32

Android系统中进程间不能共享内存。为使其他APP共享本APP提供的服务,Android采用了RPC(Remote Procedure Call)。Android使用一种接口定义语言来公开服务的接口。我们知道Android4大组件中的3个(Activity、BroadcastReceiver、ContentProvider)都可跨进程访问,Service同样可以。我们将跨进程访问的服务称为AIDL服务。

AIDL的使用步骤:

1)创建Android项目,定义aidl文件IMyService.aidl,会在gen目录自动生成跟aidl文件相同包名的Java接口文件IMyService.java。

2)定义Service的子类,在其中定义继承IMyService.Stub的内部类MyServiceImpl。在onBind方法中返回MyServiceImpl的实例。

3)在清单文件注册该Service,其action标签name属性即该服务对外公开的action。

4)在另一个项目中绑定该服务并调用方法。

1、示例演示AIDL的用法

1)IMyService.aidl

package com.qinuli.aidltest.aidl;interface IMyService{String getValue();}
2)IMyService.java,自动生成的接口文件

/* * This file is auto-generated.  DO NOT MODIFY. * Original file: C:\\Users\\shixin\\workspace\\AIDLTest\\src\\com\\qinuli\\aidltest\\aidl\\IMyService.aidl */package com.qinuli.aidltest.aidl;public interface IMyService extends android.os.IInterface{/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implements com.qinuli.aidltest.aidl.IMyService{private static final java.lang.String DESCRIPTOR = "com.qinuli.aidltest.aidl.IMyService";/** Construct the stub at attach it to the interface. */public Stub(){this.attachInterface(this, DESCRIPTOR);}/** * Cast an IBinder object into an com.qinuli.aidltest.aidl.IMyService interface, * generating a proxy if needed. */public static com.qinuli.aidltest.aidl.IMyService asInterface(android.os.IBinder obj){if ((obj==null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin!=null)&&(iin instanceof com.qinuli.aidltest.aidl.IMyService))) {return ((com.qinuli.aidltest.aidl.IMyService)iin);}return new com.qinuli.aidltest.aidl.IMyService.Stub.Proxy(obj);}@Override 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_getValue:{data.enforceInterface(DESCRIPTOR);java.lang.String _result = this.getValue();reply.writeNoException();reply.writeString(_result);return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements com.qinuli.aidltest.aidl.IMyService{private android.os.IBinder mRemote;Proxy(android.os.IBinder remote){mRemote = remote;}@Override public android.os.IBinder asBinder(){return mRemote;}public java.lang.String getInterfaceDescriptor(){return DESCRIPTOR;}@Override public java.lang.String getValue() 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_getValue, _data, _reply, 0);_reply.readException();_result = _reply.readString();}finally {_reply.recycle();_data.recycle();}return _result;}}static final int TRANSACTION_getValue = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);}public java.lang.String getValue() throws android.os.RemoteException;}
3)MyService.java
public class MyService extends Service {public class MyServiceImpl extends IMyService.Stub{@Overridepublic String getValue() throws RemoteException {return "终于等到你";}}@Overridepublic IBinder onBind(Intent intent) {return new MyServiceImpl();}}
4)AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.qinuli.aidltest"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="21" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <service android:name="com.qinuli.aidltest.MyService">            <intent-filter >                <action android:name="com.qinuli.aidltest.aidl.IMyService"/>            </intent-filter>        </service>    </application></manifest>
5)MainActivity.java
public class MainActivity extends Activity{private static final String TAG = MainActivity.class.getSimpleName();@Overrideprotected void onCreate(Bundle savedInstanceState) {Log.d(TAG, "onCreate");super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void onClick(View v){switch(v.getId()){case R.id.btn_bind:bindService(new Intent("com.qinuli.aidltest.aidl.IMyService"), mServiceConnection, Context.BIND_AUTO_CREATE);break;case R.id.btn_call:try {Toast.makeText(this, myService.getValue(), Toast.LENGTH_SHORT).show();} catch (RemoteException e) {e.printStackTrace();}}}private IMyService myService;private ServiceConnection mServiceConnection = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {myService = IMyService.Stub.asInterface(service);}};}
6)activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    xmlns:android="http://schemas.android.com/apk/res/android">    <Button         android:id="@+id/btn_bind"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="bind"        android:onClick="onClick"/>    <Button         android:id="@+id/btn_call"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="call"        android:onClick="onClick"/></LinearLayout>

0 0