AIDL的意义及用法

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{
		@Override
		public String getValue() throws RemoteException {
			return "终于等到你";
		}
	}
	
	@Override
	public 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();
	@Override
	protected 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() {
		@Override
		public void onServiceDisconnected(ComponentName name) {
		}
		@Override
		public 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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值