AIDL
来源:互联网 发布:桂糖微盘软件开发商 编辑:程序博客网 时间:2024/05/16 09:52
AIDL(Android 接口描述语言):作用是用于进程间的通信。编译器会根据AIDL文件生成Java类,通过预先定义的接口以及Binder机制达到进程间的通信。
AIDL其实就是一个接口罢了,客户端通过bindService来与远程服务端建立连接,在该连接建立时会返回一个IBinder对象,该对象是服务端Binder的BinderProxy,客户端通过asinterface将该BinderProxy对象包装成本地的Proxy,并将远程服务端的BinderProxy对象赋值给Proxy类的mRemote字段,就是通过mRemote执行远程函数调用。
下面写一个案例:
先看一下工程结构:
注意:创建完.aidl文件后一定要先编译,如果你是用Eclipse的话会自动编译,否则java文件不会生成!还有,包名和类名一字不差!
aidl文件内容:
package com.yu.myaidl;// Declare any non-default types here with import statementsinterface SsoAuth { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. *//*** 实现授权登录*/ void ssoAuth(String userName,String pwd);}
下面是服务端代码:
public class SinaSsoAuthService extends Service{ SinaSsoImpl mBinder = new SinaSsoImpl(); @Nullable @Override public IBinder onBind(Intent intent) { return mBinder; } @Override public void onCreate() { super.onCreate(); Log.e("","### sso auth created"); } //继承自Stub类实现功能 class SinaSsoImpl extends SsoAuth.Stub{ @Override public void ssoAuth(String userName, String pwd) throws RemoteException { Log.e("", "这是新浪客户端,执行SSO登录啦,用户名:" + userName + ",密码是:" + pwd); } }}
别忘了注册服务:
<service android:name=".SinaSsoAuthService" android:exported="true" android:label="@string/app_name" android:process=":remote"> <intent-filter> <action android:name="AIDL_Action" /> </intent-filter> </service>
好了,服务端OK了,先跑起来吧!
客户端代码如下:
public class MainActivity extends Activity { SsoAuth mSsoAuth; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } //当点击登录按钮时 public void click(View view){ if(mSsoAuth==null){ //绑定服务并且进行登录 bindSsoAuthService(); }else { //直接授权登录 doSsoAuth(); } } private void bindSsoAuthService() { //绑定服务 Intent intent = new Intent("AIDL_Action"); bindService(intent,mConnection, Service.BIND_AUTO_CREATE); } ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //建立连接之后将Binder转换为mSsoAuth mSsoAuth = SsoAuth.Stub.asInterface(service); doSsoAuth(); } @Override public void onServiceDisconnected(ComponentName name) { //合理利用资源 mSsoAuth = null; } }; @Override protected void onDestroy() { super.onDestroy(); unbindService(mConnection); } private void doSsoAuth() { try { //执行登录操作,调用的是服务端的函数 mSsoAuth.ssoAuth("范冰冰","5201314"); } catch (RemoteException e) { e.printStackTrace(); } }}
效果就不演示了,LogCat会打印那句话的。
以上只是小白水平,下面看看大白水平是咋的。
这是aidl转为java的代码:
/* * This file is auto-generated. DO NOT MODIFY. * Original file: F:\\workingplace\\MyAidl\\aidl_client\\src\\main\\aidl\\com\\yu\\myaidl\\SsoAuth.aidl */package com.yu.myaidl;// Declare any non-default types here with import statementspublic interface SsoAuth extends android.os.IInterface { /** * Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.yu.myaidl.SsoAuth { private static final java.lang.String DESCRIPTOR = "com.yu.myaidl.SsoAuth"; /** * Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.yu.myaidl.SsoAuth interface, * generating a proxy if needed. */ public static com.yu.myaidl.SsoAuth asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.yu.myaidl.SsoAuth))) { return ((com.yu.myaidl.SsoAuth) iin); } return new com.yu.myaidl.SsoAuth.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_ssoAuth: { data.enforceInterface(DESCRIPTOR); java.lang.String _arg0; _arg0 = data.readString(); java.lang.String _arg1; _arg1 = data.readString(); this.ssoAuth(_arg0, _arg1); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements com.yu.myaidl.SsoAuth { 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; } /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ @Override public void ssoAuth(java.lang.String userName, java.lang.String pwd) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(userName); _data.writeString(pwd); mRemote.transact(Stub.TRANSACTION_ssoAuth, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } static final int TRANSACTION_ssoAuth = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); } /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ public void ssoAuth(java.lang.String userName, java.lang.String pwd) throws android.os.RemoteException;}
简要分析下:第12行生成了Stub静态内部类,该类继承了Binder,并且实现了SsoAuth接口。看到第26行asInterface(),在这个函数中判断obj的类型,如果是本地的话,将它转换为SsoAuth类型,相反,会生成内一个内部类Proxy来包装obj,将器复制给Proxy的mremote字段。63和84行,Proxy同样实现了SsoAuth接口,它是通过Binder机制来与远程进程进行交互。
客户端的调用会通过Binder机制传递到服务端,最终调用Stub类中的onTransact()。49行,由于客户端发送请求时的类型是TRANSACTION_ssoAuth(通过91行可知),满足这个类型的话,就会执行55行。因此:这二端的Binder机制就对接上了。
public void onServiceConnected(ComponentName name, IBinder service) { //建立连接之后将Binder转换为mSsoAuth mSsoAuth = SsoAuth.Stub.asInterface(service); doSsoAuth(); }
上面这行代码:Service对象其实是BinderProxy类型经过asInterface()转换后被包装成了Proxy类型,但在调用的时候,执行的是服务端的ssoAuth(),SinaSsoImpl实例mBinder被服务端包装成BinderProxy类型,再经过客户端的Proxy进行包装,通过Binder机制进行数据传输实现进程间的调用。
- AIDL
- aidl
- AIDL
- AIDL
- AIDL
- AIDL
- AIDL
- aidl
- aidl
- AIDL
- AIDL
- aidl
- AIDL
- AIDL
- AIDL
- aidl
- aidl
- AIDL
- mysql远程连接
- spark join操作
- (win32)解决虚拟按键被输入法截获
- MySQL 乱码问题
- 华中农业大学第四届程序设计大赛网络同步赛Problem J: Arithmetic Sequence
- AIDL
- 驱动开发杂记1
- 【LeetCode】95. Unique Binary Search Trees II
- sublime 编译提示js
- 如何修改tomcat的账号密码
- Hive体系结构(二)Hive的执行原理、与关系型数据库的比较
- Java编程思想[一]对象
- 自定义异常
- 解决unity5.3出现的: [VRDevice] Initialization of device oculus failed 问题