关于AIDL的介绍在文档:docs/guide/developing/tools/aidl.html
关于IBinder的介绍在文档:docs/reference/android/os/IBinder.html
以及Binder:docs/reference/android/os/Binder.html
本文将以一个例子来和你分享使用AIDL的基础技能,这个例子里有:
1、一个类mAIDLActivity,继承Activity。里面有三个按钮,text分别为StartService,StopService,CallbackTest。
3、两个AIDL文件:forService.aidl和forActivity.aidl。对应名字,在Service和Activity中分别有对象需要用到它们定义的接口。
<service android:name=".mAIDLService" android:process=":remote"> </service>
在Eclipse中它们将被自动编译为forActivity.java和forService.java,它们存放在gen目录下。为了方便手头无法演练的读者,代码贴上,不用细看。
- /*
- * This file is auto-generated. DO NOT MODIFY.
- * Original file: D://workspace//AIDLTest//src//com//styleflying//AIDL//forActivity.aidl
- */
- package com.styleflying.AIDL;
- import java.lang.String;
- import android.os.RemoteException;
- import android.os.IBinder;
- import android.os.IInterface;
- import android.os.Binder;
- import android.os.Parcel;
- public interface forActivity extends android.os.IInterface
- {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends android.os.Binder implements com.styleflying.AIDL.forActivity
- {
- private static final java.lang.String DESCRIPTOR = "com.styleflying.AIDL.forActivity";
- /** Construct the stub at attach it to the interface. */
- public Stub()
- {
- this.attachInterface(this, DESCRIPTOR);
- }
- /**
- * Cast an IBinder object into an forActivity interface,
- * generating a proxy if needed.
- */
- public static com.styleflying.AIDL.forActivity 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 com.styleflying.AIDL.forActivity))) {
- return ((com.styleflying.AIDL.forActivity)iin);
- }
- return new com.styleflying.AIDL.forActivity.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_performAction:
- {
- data.enforceInterface(DESCRIPTOR);
- this.performAction();
- reply.writeNoException();
- return true;
- }
- }
- return super.onTransact(code, data, reply, flags);
- }
- private static class Proxy implements com.styleflying.AIDL.forActivity
- {
- 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 void performAction() throws android.os.RemoteException
- {
- android.os.Parcel _data = android.os.Parcel.obtain();
- android.os.Parcel _reply = android.os.Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_performAction, _data, _reply, 0);
- _reply.readException();
- }
- finally {
- _reply.recycle();
- _data.recycle();
- }
- }
- }
- static final int TRANSACTION_performAction = (IBinder.FIRST_CALL_TRANSACTION + 0);
- }
- public void performAction() throws android.os.RemoteException;
- }
- package com.styleflying.AIDL;
- import android.app.Activity;
- import android.content.ComponentName;
- import android.content.Context;
- import android.content.Intent;
- import android.content.ServiceConnection;
- import android.os.Bundle;
- import android.os.IBinder;
- import android.os.RemoteException;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class mAIDLActivity extends Activity {
- private static final String TAG = "AIDLActivity";
- private Button btnOk;
- private Button btnCancel;
- private Button btnCallBack;
- private void Log(String str) {
- Log.d(TAG, "------ " + str + "------");
- }
- private forActivity mCallback = new forActivity.Stub() {
- public void performAction() throws RemoteException
- {
- Toast.makeText(mAIDLActivity.this, "this toast is called from service", 1).show();
- }
- };
- forService mService;
- private ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className,
- IBinder service) {
- mService = forService.Stub.asInterface(service);
- try {
- mService.registerTestCall(mCallback);}
- catch (RemoteException e) {
- }
- }
- public void onServiceDisconnected(ComponentName className) {
- Log("disconnect service");
- mService = null;
- }
- };
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- setContentView(R.layout.main);
- btnOk = (Button)findViewById(R.id.btn_ok);
- btnCancel = (Button)findViewById(R.id.btn_cancel);
- btnCallBack = (Button)findViewById(R.id.btn_callback);
- btnOk.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- Bundle args = new Bundle();
- Intent intent = new Intent(mAIDLActivity.this, mAIDLService.class);
- intent.putExtras(args);
- bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
- startService(intent);
- }
- });
- btnCancel.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- unbindService(mConnection);
- //stopService(intent);
- }
- });
- btnCallBack.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v)
- {
- try
- {
- mService.invokCallBack();
- } catch (RemoteException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- });
- }
- }
- package com.styleflying.AIDL;
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
- import android.os.RemoteCallbackList;
- import android.os.RemoteException;
- import android.util.Log;
- public class mAIDLService extends Service {
- private static final String TAG = "AIDLService";
- private forActivity callback;
- private void Log(String str) {
- Log.d(TAG, "------ " + str + "------");
- }
- @Override
- public void onCreate() {
- Log("service create");
- }
- @Override
- public void onStart(Intent intent, int startId) {
- Log("service start id=" + startId);
- }
- @Override
- public IBinder onBind(Intent t) {
- Log("service on bind");
- return mBinder;
- }
- @Override
- public void onDestroy() {
- Log("service on destroy");
- super.onDestroy();
- }
- @Override
- public boolean onUnbind(Intent intent) {
- Log("service on unbind");
- return super.onUnbind(intent);
- }
- public void onRebind(Intent intent) {
- Log("service on rebind");
- super.onRebind(intent);
- }
- private final forService.Stub mBinder = new forService.Stub() {
- @Override
- public void invokCallBack() throws RemoteException
- {
- callback.performAction();
- }
- @Override
- public void registerTestCall(forActivity cb) throws RemoteException
- {
- callback = cb;
- }
- };
- }
注意onBind(),它的返回类型为IBinder,返回了一个mBinder,看看mBinder的定义:
private final forService.Stub mBinder = new forService.Stub() {
@Override
public void invokCallBack() throws RemoteException
{
callback.performAction();
}
@Override
public void registerTestCall(forActivity cb) throws RemoteException
{
callback = cb;
private forActivity mCallback = new forActivity.Stub()
很啰嗦,只为了能把这个细节说清楚。请大家认真看,我尽量避免错别字、混乱的大小写和逻辑不清的语法,相信你会看明白。是不是很简单?再啰嗦一下,做一个大致总结,我们使用AIDL是要做什么呢:
至于如何获得远程的Stub,参看上面的代码,看mConnection、registerTestCall、onRebind,它们展示了一种方法。
欢迎阅读、收藏本文。例子随手写的,功能只在演示AIDL的使用。您可以转载本文,但请勿盲目乱贴。不是我小气,我不权威,我怕它被贴到泛滥,以讹传讹,害了人。
来源:http://blog.youkuaiyun.com/saintswordsman/article/details/5130947