文档章节

Android AIDL——实现机制浅析

andy_android
 andy_android
发布于 2011/12/17 13:53
字数 1157
阅读 5242
收藏 6
1.基于前面写的aidl使用,这段时间准备研究ActivityManager框架,对aidl进行了更深入的研究,因为android框架大量使用了 进程通信机制,所以,在研究android framework前认真研究一下AIDL的实现机制十分有必要的

  2.前面讲了aidl是 Android Interface definition language的缩写,它是一种进程通信接口的描述,通过sdk解释器对器进行编译,会把它编译成java代码在gen目录下,类路径与aidl文件的 类路径相同。

  3.aidl接口
package com.cao.android.demos.binder.aidl; 
import com.cao.android.demos.binder.aidl.AIDLActivity;
interface AIDLService {  
    void registerTestCall(AIDLActivity cb);  
    void invokCallBack();
}

它编译后生成的java文件如下

AIDLService.java详细描述了aidl接口的实现,看上面图示,AIDLActivity.aidl编译成了一个接口 AIDLActivity,一个存根类Stub,一个代理类Proxy
public interface AIDLService extends android.os.IInterface//与AIDLActivity.aidl中定义的接口对应的java接口实现
public static abstract class Stub extends android.os.Binder implements com.cao.android.demos.binder.aidl.AIDLService
//继承android.os.Binder,在onTransact完成对通信数据的接收,通过不同通信参数code调用AIDLService接口方 法,并回写调用返回结果AIDLService接口方法需要在
//服务端实现
private static class Proxy implements com.cao.android.demos.binder.aidl.AIDLService
//实现AIDLService接口方法,但是方法只是执行代理远程调用操作,具体方法操作在远端的Stub存根类中实现

 

总的来说,AIDLActivity.aidl编译会生成一个AIDLActivity接口,一个stub存根抽像类,一个proxy代理类,这个 实现其实根axis的wsdl文件编译生成思路是一致的,
stub存根抽像类需要在服务端实现,proxy代理类被客户端使用,通过stub,proxy的封装,屏蔽了进程通信的细节,对使用者来说就只是一个 AIDLActivity接口的调用

 

  4.根据以上思路使用aidl再看一下AIDLService调用实现代码
--1.在服务端实现AIDLService.Stub抽象类,在服务端onBind方法中返回该实现类
--2.客户端绑定service时在ServiceConnection.onServiceConnected获取onBind返回的IBinder 对象
        private ServiceConnection mConnection = new ServiceConnection() {
                public void onServiceConnected(ComponentName className, IBinder service) {
                        Log("connect service");
                        mService = AIDLService.Stub.asInterface(service);
                        try {
                                mService.registerTestCall(mCallback);
                        } catch (RemoteException e) {

                        }
                }
        注意mConnection在bindservice作为调用参数:bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
--3.AIDLService.Stub.asInterface(service);
public static com.cao.android.demos.binder.aidl.AIDLService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
//如果bindService绑定的是同一进程的service,返回的是服务端Stub对象本省,那么在客户端是直接操作Stub对象,并不进行进程 通信了
if (((iin!=null)&&(iin instanceof com.cao.android.demos.binder.aidl.AIDLService))) {
return ((com.cao.android.demos.binder.aidl.AIDLService)iin);
}
//bindService绑定的不是同一进程的service,返回的是代理对象,obj==android.os.BinderProxy对象,被包 装成一个AIDLService.Stub.Proxy代理对象
//不过AIDLService.Stub.Proxy进程间通信通过android.os.BinderProxy实现
return new com.cao.android.demos.binder.aidl.AIDLService.Stub.Proxy(obj);
}
--4.调用AIDLService接口方法,如果是同一进程,AIDLService就是service的Stub对象,等同直接调用Stub对象实现 的AIDLService接口方法
如果是一个proxy对象,那就是在进程间调用了,我们看一个客户端调用的例子:
                        public void onClick(View v) {
                                Log("AIDLTestActivity.btnCallBack");
                                try {
                                        mService.invokCallBack();
                                } catch (RemoteException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                }
        --mService.invokCallBack()等同调用Proxy.invokCallBack,这个时候是进程间调用,我们看代理方法的实现
public void invokCallBack() throws android.os.RemoteException
{
//构造一个Parcel对象,该对象可在进程间传输
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
//DESCRIPTOR = "com.cao.android.demos.binder.aidl.AIDLService",描述了调用哪个Stub对象
_data.writeInterfaceToken(DESCRIPTOR);
//Stub.TRANSACTION_invokCallBack标识调用Stub中哪个接口方法,mRemote在是构造Proxy对象的参数 obj,也就是public void onServiceConnected(ComponentName className, IBinder service)
//中的service参数,它是一个BinderProxy对象,负责传输进程间数据。
mRemote.transact(Stub.TRANSACTION_invokCallBack, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
--5.BinderProxy.transact 该方法本地化实现
   public native boolean transact(int code, Parcel data, Parcel reply,
            int flags) throws RemoteException;
        //对应实现的本地化代码 /frameworks/base/core/jni/android_util_Binder.cpp->static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
                                                jint code, jobject dataObj,
                                                jobject replyObj, jint flags)
  //具体进程通信在c代码中如何实现,以后再深入研究。
--6.服务端进程数据接收
        --调用堆栈
        ##AIDLService.Stub.onTransact
        ##AIDLService.Stub(Binder).execTransact
        ##NativeStart.run
        --AIDLService.Stub.onTransact
        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_registerTestCall:
{
data.enforceInterface(DESCRIPTOR);
com.cao.android.demos.binder.aidl.AIDLActivity _arg0;
_arg0 = com.cao.android.demos.binder.aidl.AIDLActivity.Stub.asInterface(data.readStrongBinder());
this.registerTestCall(_arg0);
reply.writeNoException();
return true;
}
//TRANSACTION_invokCallBack由前面客户端调用的时候transact方法参数决 定,code==TRANSACTION_invokCallBack,执行
//invokCallBack方法,方法由继承Stud的服务端存根类实现。
case TRANSACTION_invokCallBack:
{
data.enforceInterface(DESCRIPTOR);
this.invokCallBack();
reply.writeNoException();
return true;
}

5.里面设置本地C代码的调用,我没有深入研究,随着后面我对android框架的深入,我会发blog进一步说民底层C代码是如何实现进程通信 的,关于AIDL进程通信,暂时研究到这里。

© 著作权归作者所有

andy_android
粉丝 8
博文 4
码字总数 9692
作品 0
南京
高级程序员
私信 提问
加载中

评论(3)

andy_android
andy_android 博主

引用来自“涂建韬”的评论

没法看,太混乱

去csdn看吧,http://blog.csdn.net/andy_android/
涂建韬
涂建韬
没法看,太混乱
n
nbaertuo
排版太乱。文字和代码太多,能配合点图吗?图最直观咯。
Android AIDL浅析及异步调用

AIDL:Android Interface Definition Language,即 Android 接口定义语言。 AIDL 是什么 Android 系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。 为了使其...

cspecialy
2018/05/20
0
0
知识总结 插件化学习 Binder机制原理

Binder是android系统特有IPC方式,安卓平台中的各种服务交互基本都是Binder机制实现,理解和掌握Binder机制的实现原理可有效提升软件性能优化点,同时Binder机制的应用也是动态代理方式实现插...

常兴E站
2017/06/05
0
0
ActivityManager讲解

1.ActivityManager是android框架的一个重要部分,它负责一新ActivityThread进程创建,Activity生命周期的维护,本blog就是着手对ActivityManager框架作一个整体的了解 2.先看一个静态类结构图...

天高空
2012/03/20
6.8K
0
简单音乐播放实例的实现,Android Service AIDL 远程调用服务

Android Service是分为两种: 本地服务(Local Service): 同一个apk内被调用 远程服务(Remote Service):被另一个apk调用 远程服务需要借助AIDL来完成。 AIDL 是什么 AIDL (Android Inte...

baisou
2013/07/27
1K
0
android基础知识05:四大组件之service 02:远程调用

本文主要介绍service相关内容。包括两篇文章: android基础知识05:四大组件之service 01 android基础知识05:四大组件之service 02:远程调用 android基础知识05:四大组件之service 03:实...

迷途d书童
2012/03/23
356
0

没有更多内容

加载失败,请刷新页面

加载更多

浅谈Command命令模式

一、前言 命令也是类,将命令作为一个类来保存,当要使用的时候可以直接拿来使用,比如脚本语言写出的脚本,只需要一个命令就能执行得到我们想要的需要操作很长时间才能得到的结果。这是一个...

青衣霓裳
9分钟前
1
0
Less导入指令

在标准CSS中,@import 规则必须位于所有其他类型的规则之前。但是Less.js不在乎我们将 @import 语句放在什么位置。 @import 伪指令常用于在代码中导入文件,它将Less 代码分布在不同的文件上...

凌兮洛
10分钟前
1
0
【apk】空包签名

命令语法 jarsigner -verbose -keystore [keystorePath] -signedjar [apkOut] [apkIn] [alias] 例 子: jarsigner -verbose -keystore F:\签名\laidianyi_customer.keystore -signedjar F:\......

Agnes2017
14分钟前
2
0
虚拟化的操作技巧!

从物理基础设施迁移到虚拟基础设施时,虚拟环境的设计和布局应模仿物理做法,企业级虚拟化软件允许创建虚拟交换机,虚拟局域网(VLANS)和私有网络可以协助迁移,分析物理和逻辑网络图,复制...

青果云小潘
17分钟前
2
0
SEO网站运营助手

SEO网站运营助手有哪些功能? 提交: 百度链接主动提交 + 熊掌号周推(支持500万条提交额,所以合并在一起提交) 更新: 网站内容改动后,对于已收录的链接,可以选择更新 查询: 对百度收录判断...

NoCome
20分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部