Java层Binder全解析。

文章仅仅用于个人的学习记录,基本上内容都是网上各个大神的杰作,此处摘录过来以自己的理解学习方式记录一下。
个人学习参考的大神连接:
1、概述。
       Java层的Binder,其实就是对底层的Binder的真正实现的一个封装,最终还是通过JNI技术调用到C/C++代码的实现。
  Java层的Binder相关代码的很多的命名规范和C/C++层的基本保持一致。此整理是在对Binder有一定的认识后,个人用于
  学习记录。

2、JNI层的知识。
      学习Java层的Binder知识的时候了解到是通过JNI调用到运行库的,但是当时并不知道具体是那些库函数的调用。此处作
为学习整理,先把这方面的知识点大概的列举出来,方便后文的分析。
      在源码工程的android/frameworks/base/core/jni/android_util_Binder.cpp当中实现了绝大部分的和java层Binder相
关的功能。

下面介绍一下核心的变量和方法:
   
   
//native层的一个结构体,用来表示java层的Binder类在JNI层的使用情况。以便对java层的操作。
static struct bindnative_offsets_t
{
jclass mClass //用来连接java层的Binder类
jmethodID mExectransact; //用来连接java层Binder类的execTransact函数
jfieldID mObject //用来连接java层Binder类的成员变量 mObject。
} gBinderOffsets; //这个结构体的名字,感觉上不应该有offsets.
    
    
//同理是表示java层的BinderProxy类的。
static struct binderproxy_offsets_t
{
jclass mclass;//连接java中的BinderProxy类。
jmethodID mConstructor;//java中BinderProxy类的构造。
jmethodID mSendDeathNotice //对应的SendDeathNotice方法.
 
//对应java中的BinderProxy类,成员变量mObject.
jfiledID mObject;
//对应成员变量mSelf. 保存Java层的BinderProxy对象的弱引用,方便,Natvie层管理生命周期。
jfiledID mSelf;
jfiledID mOrgue;//对应成员变量mOrgue.和接受客户端也就是代理端死亡通知消息有关。
}gBinderProxyOffsets;
            
    
    
//同理是表示java层的BinderInternal类的。
static struct binderinternal_offsets_t
{
jclass mclass;//连接java中的BinderInternal类.
jmethodID mForceGC;
}gBinderInternalOffsets;
          重要的方法有如下:
          先是 register_android_os_Binder这个方法是由AndroidRuntime在进行调用。此方法的内部分别调用另外的三个具体的
   方法初始化,我们前面所说的三个结构体,也就是 java中的Binder、BinderProxy、BinderInternal和   Native层中这三个类
   的关系。
   
   
int register_android_os_Binder(JNIEnv* env)
{
if (int_register_android_os_Binder(env) < 0)//初始化Binder类相关
return -1;
if (int_register_android_os_BinderInternal(env) < 0)//初始化BinderInternal类相关
return -1;
if (int_register_android_os_BinderProxy(env) < 0)//初始化BinderProxy类相关。
return -1;
 
jclass clazz;
 
......//省略和Log以及权限等相关的.
return 0;
}
          初始化 gBinderOffsets结构体:
   
   
const char* const kBinderPathName = "android/os/Binder";
static int int_register_android_os_Binder(JNIEnv* env)
{
jclass clazz;
 
clazz = env->FindClass(kBinderPathName);//获得一个java中的Binder类对象
LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder");
 
//下面就是把java层的对象或者方法转换成JNI层的.
gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
gBinderOffsets.mExecTransact
= env->GetMethodID(clazz, "execTransact", "(IJJI)Z");
assert(gBinderOffsets.mExecTransact);
 
//两个mObject对应起来.
gBinderOffsets.mObject
= env->GetFieldID(clazz, "mObject", "J");
assert(gBinderOffsets.mObject);
 
//调用到AndroidRunTime完成最终注册。
return AndroidRuntime::registerNativeMethods(
env, kBinderPathName,
gBinderMethods, NELEM(gBinderMethods));
}
          初始化 gBinderProxyOffsets结构体:
   
   
const char* const kBinderProxyPathName = "android/os/BinderProxy";
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
jclass clazz;
 
......//省略错误信息的处理.
clazz = env->FindClass(kBinderProxyPathName);
LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.BinderProxy");
//同样是把Java层的对象、变量、方法保存到相应的JNI层的对应的结构中.
gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
gBinderProxyOffsets.mConstructor
= env->GetMethodID(clazz, "<init>", "()V");
assert(gBinderProxyOffsets.mConstructor);
gBinderProxyOffsets.mSendDeathNotice
= env->GetStaticMethodID(clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V");
assert(gBinderProxyOffsets.mSendDeathNotice);
 
gBinderProxyOffsets.mObject
= env->GetFieldID(clazz, "mObject", "J");
assert(gBinderProxyOffsets.mObject);
gBinderProxyOffsets.mSelf
= env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;");
assert(gBinderProxyOffsets.mSelf);
gBinderProxyOffsets.mOrgue
= env->GetFieldID(clazz, "mOrgue", "J");
assert(gBinderProxyOffsets.mOrgue);
 
clazz = env->FindClass("java/lang/Class");
LOG_FATAL_IF(clazz == NULL, "Unable to find java.lang.Class");
gClassOffsets.mGetName = env->GetMethodID(clazz, "getName", "()Ljava/lang/String;");
assert(gClassOffsets.mGetName);
 
return AndroidRuntime::registerNativeMethods(
env, kBinderProxyPathName,
gBinderProxyMethods, NELEM(gBinderProxyMethods));
}
          初始化 gBinderInternalOffsets结构体
   
   
const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
static int int_register_android_os_BinderInternal(JNIEnv* env)
{
jclass clazz;
 
clazz = env->FindClass(kBinderInternalPathName);
LOG_FATAL_IF(clazz == NULL, "Unable to find class com.android.internal.os.BinderInternal");
 
gBinderInternalOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
gBinderInternalOffsets.mForceGc
= env->GetStaticMethodID(clazz, "forceBinderGc", "()V");
assert(gBinderInternalOffsets.mForceGc);
 
return AndroidRuntime::registerNativeMethods(
env, kBinderInternalPathName,
gBinderInternalMethods, NELEM(gBinderInternalMethods));
}
            至此介绍完了 android_util_Binder.cpp文件中 主要的变量和方法,以及它们的初始化的过程,分析的过程中还会遇到
     一些JNI层的方法,这些具体情况具体在分析。总的来说,AndroidRuntime.cpp中调用了 register_android_os_Binder方
    法,进而分别调用到不同的初始化方法中,对相应的结构体进行初始化,以方便native binder和java层binder进行通信。

3、代码架构。
      下面这张图是邓平凡,邓老师的博客中图。此处仅仅用做记录:

       

            在Android中要求所有的Android实体(无论什么代理端远程端)都必须实现IBinder接口。在java层还有一个IInter 
      face在此图中没有体现出来。这两个接口都是用来规范Binder使用时的一些协议和方法名称。让子类具体实现。
            IInterface仅仅声明一个抽象方法asBinder()它返回IBinder对象,也就是可以返回Binder和BinderProxy.
   
   
public interface IInterface
{
/**
* Retrieve the Binder object associated with this interface.
* You must use this instead of a plain cast, so that proxy objects
* can return the correct result.
*/
public IBinder asBinder();
}
           下面我们列出来IBinder的一些重要的方法。
   
   
public interface IBinder {
/**
* Attempt to retrieve a local implementation of an interface
* for this Binder object. If null is returned, you will need
* to instantiate a proxy class to marshall calls through
* the transact() method.
*/
public IInterface queryLocalInterface(String descriptor);
/**
* Perform a generic operation with the object.
*
* @param code The action to perform. This should
* be a number between {@link #FIRST_CALL_TRANSACTION} and
* {@link #LAST_CALL_TRANSACTION}.
* @param data Marshalled data to send to the target. Must not be null.
* If you are not sending any data, you must create an empty Parcel
* that is given here.
* @param reply Marshalled data to be received from the target. May be
* null if you are not interested in the return value.
* @param flags Additional operation flags. Either 0 for a normal
* RPC, or {@link #FLAG_ONEWAY} for a one-way RPC.
*/
public boolean transact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException;
/**
* Interface for receiving a callback when the process hosting an IBinder
* has gone away.
*
* @see #linkToDeath
*/
public interface DeathRecipient {
public void binderDied();
}
}

4、实例学习。
      下面就以例子学习的方式整理整个流程。此处的例子用的是罗升阳,罗老师博客中的,个人仅仅是为了记录整理学习过程。
       从我们使用者的角度来看,实现一个完整的系统及被服务,供别的进程调用的步骤如下:
              1、接口的定义。
                    我们会先写一个aidl文件,然后让自己写的具体的service 继承 aidl文件名.Stub.此处的这个aidl文件会在编译的时
               候,由工具为我们生成一个标准的java文件。里面有Binder的一些标准实现。  
              2、再注册到ServiceManager当中,ServiceManager.addService("hello",new HelloService());
                    此处是直接完全用的罗老师的,"hello"字符串代表的这个service的名字描述,以后要通过它进行获取。而后面的
                     HelloService就是我们自己的服务具体实现的地方。这样就完成了注册。
              3、别的服务想要是用的时候,必须通过ServiceManager.getService(" hello ");进行获取。
              4、最后通过一个如下的转换得到I HelloService 接口的实例,
                     private IHelloService helloService = null;
                     helloService = IHelloService.Stub.asInterface( ServiceManager.getService("hello"));
          从我们的Binder的学习角度来分析。
                 我们知道java层的binder是对native层的binder的一个封装,那么我们就需要依次获得native层的相应的角色的实
          现就可以一步一步的分析出结果了。
                 1、获取远程service manager 的java层的远程接口。(service manager端)
                      无论你注册还是取出服务你都需要通过这个管理,这个管理就时我们native  层的service manager。注意千万不
                      要把它和java层的ServiceManager混为一谈。
                 2、定义我们服务接口,并且把它注册到service manager当中。(server端)
                 3、通过service manager获取我们服务的java远程接口,并通过相应的接口调用相应的方法。(client端)
       下面我们就来一点点的学习binder java层的具体的实现。前面的可以说都是一些必备的基础知识。
        
        4.1、获取native层的service manager的java远程接口.(service manager)
                我们前面一再强调过这个接口的重要性。它是用来管理Binder对象的注册和获取,也就是管理我们的服务。我们的
                服务就是要实现成一个binder对象,然后利用Android的binder机制进行跨进程通信。这一步我们在java层使用时
                候经常会注意不到,因为我们直接就 ServiceManager.addService()也没看到先获取什么东西啊。其实进入到
                ServiceManager的 addService()当中我们就发现,是Android在内部调用了相关的方法。
                我们查看ServiceManager的源码中相关的方法如下
   
   
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
    
    
private static IServiceManager sServiceManager;
//获取IServiceManager的对象,IServiceManager是一个接口此处就是获得它的实现类的一个对象,
//其实最终就是ServiceManagerProxy类.(该类和ServiceManagerNative在一个java文件当中)
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
//下面就相当于sServiceManager = ServiceManagerNative.asInterface(new BinderProxy(0));
// sServiceManager = new ServiceManagerProxy(new BinderProxy());
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
           由上面首先就可以看出IServiceManager是一个单例模式。此处请忽略代码中的注释,都是自己为了方便理解加上去的
      分析到后面就知道这个结论了。现在看来是又调入到了 ServiceManagerNative类当中。但在此之前我们应该把,参数里面
      的 BinderInternal.getContextObject().分析一下。
           在 BinderInternal.java类中 getContextObject就是一个native的函数如下:
            public static final native IBinder getContextObject();
           对应到 android_util_Binder.cpp中的方法是 android_os_BinderInternal_getContextObject
   
   
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
//BpBinder对象,它的句柄值是0,相当于:sp<IBinder> b = new BpBinder(0);
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
          可以看到最终是获得了一个句柄值为0的BpBinder对象,注意这个对象是一个native的对象,并且它就是远程的service
      manager的代理端。至于这个   ProcessState::self()->getContextObject(NULL);的具体实现分析,请参考罗老师文章。接
     下来我们还需要把这个native层的BpBinder对象转换成java层的BinderProxy,然后java层才能正确使用。
         
  
  
//把本地的IBinder对象转换成java层对应的Ibinder对象,val传入的本地Ibinder对象。
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
if (val == NULL) return NULL;
//里传进来的参数是一个BpBinder的指针
//而BpBinder::checkSubclass继承于父类IBinder::checkSubclass,它什么也不做就返回false
if (val->checkSubclass(&gBinderOffsets)) {
jobject object = static_cast<JavaBBinder*>(val.get())->object();
LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
return object;
}
......//省去一些注释和锁代码,方便观察
//此处就用到了gBinderProxyOffsets,首先来获取一下看看是不是已经有这个object了.
//第一次走到这这里object==null.
jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
if (object != NULL) {
jobject res = jniGetReferent(env, object);
if (res != NULL) {
ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
return res;
}
LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
android_atomic_dec(&gNumProxyRefs);
val->detachObject(&gBinderProxyOffsets);
env->DeleteGlobalRef(object);
}
//不存在的话,新建一个.
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) {//创建成功的话,做一些赋值的处理.
//要把native的BpBinder对象和java层的BinderProxy对象关联起
//BinderProxy.mObject成员变量记录了这个BpBinder对象的地址(val.get)。
env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
val->incStrong((void*)javaObjectForIBinder);
 
jobject refObject = env->NewGlobalRef(
env->GetObjectField(object, gBinderProxyOffsets.mSelf));
//接下来放到BpBinder当中那么下次调用findObject就可以得到它了.
val->attachObject(&gBinderProxyOffsets, refObject,
jnienv_to_javavm(env), proxy_cleanup);
 
// Also remember the death recipients registered on this proxy
sp<DeathRecipientList> drl = new DeathRecipientList;
drl->incStrong((void*)javaObjectForIBinder);
env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
 
// Note that a new object reference has been created.
android_atomic_inc(&gNumProxyRefs);
incRefsCreated(env);
}
 
return object;//最后返回回去.
}
            层层返回于是最后 BinderInternal.getContextObject() 就相当于new BinderProxy.(注意这个BinderProxy对应的可
        是底层的 service manager远程代理也就是BpBinder(0))最后回到 ServiceManager.java中的 getIServiceManager方
        法中来 sServiceManager = ServiceManagerNative.asInterface(new BinderProxy()) 调用到 ServiceManagerNative。
  
  
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);
}
           值得提一下的是 ServiceManagerNative 继承Binder实现了IServiceManager接口,而 IServiceManager接口继承自
      IInterface。 IInterface前面已说过,此处贴出 IServiceManager声明的接口。
   
   
public interface IServiceManager extends IInterface
{
 
public IBinder getService(String name) throws RemoteException;
public IBinder checkService(String name) throws RemoteException;
 
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException;
 
public String[] listServices() throws RemoteException;
 
public void setPermissionController(IPermissionController controller)
throws RemoteException;
static final String descriptor = "android.os.IServiceManager";
 
int GET_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
int CHECK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+1;
int ADD_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+2;
int LIST_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+3;
int CHECK_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+4;
int SET_PERMISSION_CONTROLLER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+5;
}
           我们接着分析 ServiceManagerNative的asInterface方法。首先会调用obj. queryLocalInterface方法,此处传入的是一
    个BinderProxy的对象,而在BinderProxy对象中 queryLocalInterface方法什么也没做仅仅是返回null
   
   
//代理端的这个查询本地接口返回的是null.
public IInterface queryLocalInterface(String descriptor) {
return null;
}
          但是假如传入的是Binder对象的话,在调用了一定的方法的时候会返回IInterface一个具体对象.
   
   
private IInterface mOwner;
 
public void attachInterface(IInterface owner, String descriptor) {
mOwner = owner;
mDescriptor = descriptor;
}
 
public IInterface queryLocalInterface(String descriptor) {
if (mDescriptor.equals(descriptor)) {
return mOwner;
}
return null;
}
         此时由于是BinderProxy所以返回null,最终走到 new ServiceManagerProxy(obj);实例化了一个ServiceanagerProxy对
     象,并在构造中传入了BinderProxy对象。
   
   
class ServiceManagerProxy implements IServiceManager {//位于ServiceManagerNative.java文件中
private IBinder mRemote;
public ServiceManagerProxy(IBinder remote){
mRemote = remote;
}
}
     这个在前面的分析中可知BinderProxy的mObject中存放着native的service manager 的远程代理对象ServiceManager
     Proxy 也就是在JNI层的BpBinder(0)的地址.这样就算是建立起了java层和native层的 service manager的联系通过JNI层的
     gBinderProxyOffsets。
         至此获取service manager的java远程接口的过程就算是完成了。
     
       4.2、定义服务接口(服务端)
             我们还是以罗老师博客中的服务为例,显示贴出来aidl文件的编写。
  
  
package android.os;
interface IHelloService
{
void setVal(int val);
int getVal();
}
           此处不用理会里面的函数的具体含义,我们旨在理解整个流程。这个aidl文件编译后会生成IHelloService.java文件。下
      面我们来分析一下这个文件。(所有的aidl都会按照一定的标准生成,大概是方便书写吧,减少开发难度)
  
  
  
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: frameworks/base/core/java/android/os/IHelloService.aidl
*/
package android.os;
public interface IHelloService extends android.os.IInterface
{
//抽象类名字都是这个Stub且是公共的.所以外部就可以 IHelloService.Stub 来得到它
/** Local-side IPC implementation stub class. */
//这个Stub是一个Binder对象,还实现了IHelloService接口.!
//所以new HelloService() 这样实例化你写好的HelloService extends IHelloService.Stub的时候.
//会去实例化Binder类的构造.
public static abstract class Stub extends android.os.Binder implements android.os.IHelloService
{
private static final java.lang.String DESCRIPTOR = "android.os.IHelloService";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an android.os.IHelloService interface,
* generating a proxy if needed.
*/
public static android.os.IHelloService 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 android.os.IHelloService))) {
return ((android.os.IHelloService)iin);
}
//注意下面传入的这个obj,它此时是BinderProxy.
//返回null那么就会调用到IHelloService远程代理接口Proxy.对象
return new android.os.IHelloService.Stub.Proxy(obj);
}
public android.os.IBinder asBinder()
{
return this;
}
//由于HelloService并没有实现onTransact,所以到这里了.
@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_setVal:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
this.setVal(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_getVal:
{
data.enforceInterface(DESCRIPTOR);
//public class HelloService extends IHelloService.Stub
//最后由于本身就是Helloservice对象在调用,
// 而他又重写了这个方法,所以会调用到HelloService的具体的getVal().(完成调用).
int _result = this.getVal();
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
//内部私有的代理端的类.所以获得sevice的代理时候应该是这个.并且只能通过 asInterface()
private static class Proxy implements android.os.IHelloService
{
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;
}
//最后client使用的时候就通过远程接口代理Proxy调用到这里。
public void setVal(int val) 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.writeInt(val);
//可以看到最终是mRemote调用的,它就是实例化Proxy时候传入的参数.
//最后调用到Binder驱动程序,Binder驱动程序唤醒HelloService这个Server
mRemote.transact(Stub.TRANSACTION_setVal, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
public int getVal() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getVal, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_setVal = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_getVal = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
//抽象的成员方法.
public void setVal(int val) throws android.os.RemoteException;
public int getVal() throws android.os.RemoteException;
}
         在这个自动生成的IHelloService接口继承android.os.IInterface接口,再加上自动生成的内容。此时这个接口中有:
                 1、静态抽象的类Stub继承Binder实现了 IHelloService。
                       public static abstract class Stub extends android.os.Binder implements android.os.IHelloService.
                       注意对于这个Stub类它本身就实现了 IHelloService接口所以需要重写接口中声明的那两个方法。
                       而在这个类中内容还十分丰富,
                       1.1、私有的内部类Proxy,这个类就是我们服务的代理端,供别的进程远程获取.
                                 private static class Proxy implements android.os.IHelloService
                       1.2、方法和变量。
                                private static final java.lang.String DESCRIPTOR = "android.os.IHelloService";  
                               构造:
                                       在Stub的构造中仅仅调用了 this.attachInterface(this, DESCRIPTOR);  这个就是前面我们分析
                                queryLocalInterface的时候假如传入的Binder对象的情况用到的。由于Stub继承Binder.就会为Bin
                                der对象的mOwner赋值。并且在你调用Binder对象的 queryLocalInterface时候,将其返回。
                                方法:
                                        asInterface( (android.os.IBinder obj )是它内部非常非常重要的一个方法,当我们去获取这个接
                                口时候就会用到了。根据传入的参数要么返回一个本地端的服务引用,要么实例化内部类Proxy(obj)
                                并返回。后面这种情况非常多,以为请求通信的时候ServiceManager.getService("name")最终
                                会得到一个BinderProxy, 然后由于 queryLocalInterface为null, 去获取本地端的远程, 代理也就是
                               Proxy,并且把这个传入的参数传进去。并且把的到的这个 BinderProxy作为mRemote。
            onTransact()方法就是在通过asInterface获取到远程代理对象的时候,然后调用相应的接口,会
                               通过mRemote去和驱动打交道,进而驱动就会唤醒远程的server,然后就会调用的JavaBBinder当中的
                                onTransact,然后又调用到Binder的 execTransact()在这个函数里面会调用子类或者自己的 onTransact
                               此时就会调用到Stub的 onTransact.
                        
                 2、两个方法(就是aidl里面写的那两个)
                      public void setVal(int val) throws android.os.RemoteException;  
                      public int getVal() throws android.os.RemoteException; 

           接下来我们就应该分析这个接口的具体的实例化和注册过程了。我们是调用ServiceManager.addService("hello", new 
           HelloService())来完成实例化和注册的,那么我们先看一下HelloService的实例化过程。
                 此处一定要注意由于 HelloService extend I HelloService.Stub.而 I HelloService.Stub extends Binder.所以会先实例
           化Binder对象。我们去看看Binder的构造。
  
  
public class Binder implements IBinder {
public Binder() {
init();
......
}
private native final void init();
}
                 同样也是调用到了android_util_Binder.cpp当中。对应的方法是android_os_Binder_init
   
   
static void android_os_Binder_init(JNIEnv* env, jobject clazz)
{
JavaBBinderHolder* jbh = new JavaBBinderHolder(env, clazz);
if (jbh == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
return;
}
LOGV("Java Binder %p: acquiring first ref on holder %p", clazz, jbh);
jbh->incStrong(clazz);
env->SetIntField(clazz, gBinderOffsets.mObject, (int)jbh);
}
                 上述方法就是实例化一个JavaBBinderHolder对象,把这个对象的地址通过gBinderOffsets保存在java层的Bin der类
            的成员变量mObject当中。(至此BinderPorxy的mObject保存的是native 的BpBinder(x)地址,Binder的mObject保
            存的是native层的初始化Binder时候的一个 JavaBBinderHolder对象的地址
                  实例化完这些操作后,实例化HelloService的构造.然后去 ServiceManager.addService(..).我们前面分析过addServi
            ce的部分过程,当获取到IserviceManager对象以后,调用它的addService()方法,如下:
   
   
public void addService(String name, IBinder service)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
                利用Parcel来序列化和反序列化数据实现传输.注意此时的mRemote是BinderProxy().接下来就需要分析Pracel的
          data.writeStrongBinder(IBinder)这个很重要的方法了,前面的两个都是把相应String、int的写入到Parcel。这个是把
          Ibinder的对象写入,此时的这个service是我们new出来的,它是一个Binder对象.
               Parcel类中有如下:
               public final native void writeStrongBinder(IBinder val);可以看出来也是一个本地方法。
               对应到andorid_os_Parcel.cpp文件当中的android_os_Parcel_writeStrongBinder方法。
   
   
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jobject clazz, jobject object)
{
Parcel* parcel = parcelForJavaObject(env, clazz);
if (parcel != NULL) {
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
}
}
}
                先是调用parcelForJavaObject()把java层的Parcel对象转换成native层的Parcel对象。然后调用writeStrongBinder
          但在这个之前,还调用了ibinderForJavaObject(object)并且把一开始传入的那个IBinder对象service也就是我们HelloSe
          r vice也就是java层Binder传入了进去(此时由于它继承Binder,所以可以传入,也能体现出一点点的Binder味道)转换
          成native的JavaBBinderHoler,按理说应该转换成BBinder,这里直接多封装了一层,应该是和一些回收机制.
   
   
//把这个Java语言实现的Binder/BinderProxy对象转换为native层的JavaBBinderHolder
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
 
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);//在Binder init的时候有赋值.
//取出来当jbh不为null的时候,在JavaBBinderHolder类中,
//有一个成员变量mBinder,它的类型为JavaBBinder,而JavaBBinder类继承于BBinder类
//get就是返回的JavaBBinder.
return jbh != NULL ? jbh->get(env, obj) : NULL;//!obj注意这个参数,就是我们传入的HelloService.
}
 
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
}
}
            传入的参数首先判断Binder对象,如果是的话取出gBinderoffsets.mObject中存入的JavaBBinderHolder. 在前面实例化
       HelloService时候回去实例化Binder,然后会走到 android_util_Binder.cpp中的 android_os_Binder_init方法中,然后实例
       化了一个 JavaBBinderHolder赋值到 gBinderoffsets.mObject当中.那么我们必须要了解一下 JavaBBinderHolder了.
           
  
  
class JavaBBinderHolder : public RefBase
{
public:
sp<JavaBBinder> get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
sp<JavaBBinder> b = mBinder.promote();
if (b == NULL) {//第一调用进入到这里.
//obj就是创建的HelloService对象了,这是一个Java对象.然后用这个对象实例化了JavaBBinder
b = new JavaBBinder(env, obj);
mBinder = b;//存入到自己的成员变量.
}
return b;
}
 
sp<JavaBBinder> getExisting()
{
AutoMutex _l(mLock);
return mBinder.promote();
}
 
private:
Mutex mLock;
wp<JavaBBinder> mBinder;//里面存放的是 JavaBBinder对象.
};
          那么JavaBBinder又是怎么实现的那?
  
  
class JavaBBinder : public BBinder
{
public:
//在构造中仅仅把传入的object保存在它的成员变量mObject.
JavaBBinder(JNIEnv* env, jobject object)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
ALOGV("Creating JavaBBinder %p\n", this);
android_atomic_inc(&gNumLocalRefs);
incRefsCreated(env);
}
 
bool checkSubclass(const void* subclassID) const
{
return subclassID == &gBinderOffsets;
}
 
jobject object() const
{
return mObject;
}
 
protected:
virtual ~JavaBBinder()
{
ALOGV("Destroying JavaBBinder %p\n", this);
android_atomic_dec(&gNumLocalRefs);
JNIEnv* env = javavm_to_jnienv(mVM);
env->DeleteGlobalRef(mObject);
}
//HelloService这个Server线程被唤醒之后,就会调用JavaBBinder类的onTransact函数!!!!!
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
{
JNIEnv* env = javavm_to_jnienv(mVM);
 
ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
 
IPCThreadState* thread_state = IPCThreadState::self();
const int32_t strict_policy_before = thread_state->getStrictModePolicy();
......
//mObject就是HelloService类的一个实例对象了,就调用了HelloService.execTransact函数
//AIDL生成的文件IHelloService.java里面并没有重写它,所以会走到Binder类中.
//注意此时实例化的是HelloService!!!(不是父类什么的)
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
jthrowable excep = env->ExceptionOccurred();
 
......//异常和权限的一些处理.  
// Need to always call through the native implementation of
// SYSPROPS_TRANSACTION.
if (code == SYSPROPS_TRANSACTION) {
BBinder::onTransact(code, data, reply, flags);
}
//......  
return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}
 
virtual status_t dump(int fd, const Vector<String16>& args)
{
return 0;
}
 
private:
JavaVM* const mVM;
jobject const mObject;
};
             JavaBBinder继承了我们Binder本地端对象BBinder.我们最需要关注的就两点:1、成员变量的mObject的赋值,是把传
     入的HelloService转换成了本地的对象存入.2、onTransact(),此方法会在服务端被唤醒的时候调用,我们后面分析。
           我们总结一下 ibinderForJavaObject(xx)这个方法做的事情.取出我们前面实例化Binder是存入的JavaBBinderHolder对
     象然后调用它的get方法获取一个JavaBBinder对象,并且保存在自己的成员变量mBinder当中。而JavaBbinder也把传入的
     IBinder也是就是HelloService对象保存在自己的mObject当中.最终返回的是 JavaBBinderHolder的get方法,也就是返回
     JavaBBinder对象.
            回到android_os_Parcel_writeStrongBinder函数当中.
            此时:const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object))那么就相当于如下:
       const status_t err = parcel->writeStrongBinder((JavaBBinderHodler*)(obj.mObject));  最终写入JavaBBinder到 Parcel
      对象当中.
             执行完写入后,最终回到ServiceManagerProxy对象的addService函数当中,接着往下执行.
      mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);至于这个 mRemote我们前面已经分析过是一个Binder
      Proxy对象.它对应到native端的BpBinder(0),也就是native 端的ServiceManagerProxy.那么接下来就是BinderProxy的函数
       transact()的 实现 了。
   
   
final class BinderProxy implements IBinder{
......  
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws
RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
return transactNative(code, data, reply, flags);
}
......
public native boolean transactNative(int code, Parcel data, Parcel reply,
int flags) throws RemoteException;
......
}
          可以看到调用到native方法 transactNative,它有指向了android_util_Binder中的 android_os_BinderProxy_transact方
       法。我们只看流程的重要部分,为了方便阅读代码去掉一些不是很重要的代码.        
  
  
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags)
{
//......
//这里传进来的参数dataObj和replyObj是一个Java接口实现的Parcel类,
//由于这里是JNI层,需要把它转换为C++实现的Parcel类,
//它们就是通过android_os_Parcel中的parcelForJavaObject函数进行转换的。
Parcel* data = parcelForJavaObject(env, dataObj);
......
Parcel* reply = parcelForJavaObject(env, replyObj);
......
//分析如何获取Service Manager远程接口时曾经说到,在JNI层中,创建了一个BpBinder对象,它的句柄值为0.
//它的地址保存在gBinderProxyOffsets.mObject中,因此,这里通过下面语句得到这个BpBinder对象.
IBinder* target = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
......
//target->transact进入到Binder驱动程序,
//然后Binder驱动程序唤醒Service Manager响应这个ADD_SERVICE_TRANSACTION请求
//这里的data包含了一个JavaBBinder类型的Binder实体对象,它的mObject就是我们的HelloService.
//Service Manager收到这个ADD_SERVICE_TRANSACTION请求时,
//就会把这个Binder实体纳入到自己内部进行管理。
//当时调用getservice走到这里的时候!
//这里的reply变量里面就包括了一个HelloService的引用了。
//(类似的可以理解为前面的别的进程放进去,我在这里拿出来,实现跨进程通信)
//注意,这里的reply变量就是我们在ServiceManagerProxy.getService函数里面传进来的参数reply,它是一
//个Parcel对象.
status_t err = target->transact(code, *data, reply, flags);
......
if (err == NO_ERROR) {
return JNI_TRUE;
} else if (err == UNKNOWN_TRANSACTION) {
return JNI_FALSE;
}
signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
return JNI_FALSE;
}
           此方法中的个人注释比较多,都是整体理解是加上去了,不理解的话,看完整个再回来看一下。此时这个方法的主要处理
     是先通过gBinderOffsets.mObject取出我们前面存入的BpBinder(0)对象用来和native层的service manager打交道。然后就
     调用这个对象的transact(),此处就走到进一步的去和Binder的驱动打交道。然后Binder驱动程序会唤醒本ServiceManager
     让它去相应ADD_SERVICE_TRANSACTION这个请求。在本地service manager收到这个请求的时候,会把我们data中包含
     的Binder实体也就是HelloService纳入自己的内部进行管理,等人来get。此处和Binder程序的具体交互,不在本文讨论范
     围,感兴趣的可以看一下罗老师的博客。
          这样我们就定义好了服务接口,并且把它添加到了本地的service manager当中了。接下来就是客户端获取服务的过程了.
         
  4.3、获取服务远程代理端.
         系统级别服务的标准使用方式我们前面也提到过:
                private IHelloService helloService = null;
                 helloService = IHelloService.Stub.asInterface( ServiceManager.getService("hello"));  
        下面我们来一步步的分析。
        首先是ServiceManager.java中的getService()方法.
   
   
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
             getIServiceManager()我们前面分析过,最终就是new ServiceManagerProxy(new BinderProxy).所以我们再去看看
      ServiceManagerProxy的 getService的实现。注意:mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0)
     传入的命令码不同此处是 GET_SERVICE_TRANSACTION.
  
  
public IBinder getService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
//通过mRemote.transact来执行实际操作,mRemote是一个BinderProxy.
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
//通过下面将你前面add进去的服务的对象的引用取出来,这个HelloService的引用读出来.
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
          checkService的前几步一直到transact都和我们前面的addService类似此处不再重述。此处的这个mRemote也和前面一
     样最终还是调入到了 android_util_Binder中的 android_os_BinderProxy_transact.此方法也在前面贴了出来。
          最关键的一步status_t err = target->transact(code, *data, reply, flags);驱动根据 code去获取service,然后会添加一个
     HelloService引用到reply变量当中.reply是一个Parel变量.
         回到ServiceManagerProxy.getService()方法中接这往下执行就到了IBinder binder = reply.readStrongBinder()然后把
     这个Ibinder返回。我们就可以用这个服务去调用接口了。那么这个IBinder是什么对象那?
          reply.readStrongBinder()也就是调用到Parcel.java的相关接口实现如下:
  
  
private static native IBinder nativeReadStrongBinder(long nativePtr);
public final IBinder readStrongBinder() {
return nativeReadStrongBinder(mNativePtr);
}
        最终对应到android_os_Parcel中的 android_os_Parcel_readStrongBinder()的方法。
    
  
  
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
//先把Java语言实现的Parcel对象class转换成C++语言实现的Parcel对象parcel.
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
//接着,通过parcel->readStrongBinder函数来获得一个Binder引用。
//它最终返回来的是一个BpBinder对象.
//因此下面就相当于return javaObjectForIBinder(env, new BpBinder(handle));
//handle就是HelloService这个Binder实体在Client进程中的句柄了.
//这个句柄它是由Binder驱动程序设置的方便管理,上层不用关心它的值具体是多少.
//最后还是调用我们前面分析的javaObjectForIBinder创建一个BinderProxy对象,
//并且把刚才获得的BpBinder对象的地址保存在这个BinderProxy对象的mObject成员变量中然后返回.
return javaObjectForIBinder(env, parcel->readStrongBinder());
}
return NULL;
}
           此处parcel->readStrongBinder().内部具体的实现请参考罗老师的博客文章,它最终会返回的就是一个BPBinder(hand)
    对象,并且会精准的拿到HelloService对应的(由驱动管理实现).最后就是执行return javaObjectForIBinder(env, new 
   BpBinder(handle))这个函数。而对于 javaObjectForIBinder我们前面分析service manager的获取过程的时候已经介绍,此
   处也是相同的道理它的作用就是创建一个BinderProxy对象,并且把刚才获得的BpBinder对象的地址保存在这个BinderProxy
   对象的mObject成员变量中。(主义传入的参数是不同的前面是BpBinder(0),这次是BpBinder(handle),其实service man
   ager 就是一个特殊的Binder)
           至此ServiceManager.getService()分析完毕,回到最初的标准调用的地方。
           helloService = IHelloService.Stub.asInterface(new BinderProxy()))注意此时的 new BinderProxy()是HelloService在
     native层的BpBinder(handle)对应过来的。
           我们接着分析   IHelloService.Stub.asInterface()函数.前面我们已经把IHelloService的aidl文件自动生成的java文件代码
     贴出来了,对比着上面看。
  
  
public static android.os.IHelloService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
//注意此时传入的这个obj,它此时是BinderProxy.
//而在BinderProxy中queryLocalInterface返回null
android.os.IInterface iin = (android.os.IInterface)obj.
queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof android.os.IHelloService))) {
return ((android.os.IHelloService)iin);
}
//那么就会会去实例化IHelloService远程代理接口Proxy.对象
return new android.os.IHelloService.Stub.Proxy(obj);
}
            然后去实例化Stub内部私有类并且把我们前面ServiceManager.getService("hello")得到的,对应于HelloService          
       native层的BpBinder(handle)的BinderProxy作为参数去实例化内部Proxy类.(和ServiceManagerProxy一样)最终
       返回,这样我们就得到了HelloService服务的远程代理端,然后就可以利用这个代理端去调用相关的接口了.
       
   4.4、通过远程代理端去调用服务的接口.
           HelloService的远程接口后,就可以使用它的服务了,此处还是用的罗老师的例子.
           int val = helloService.getVal();以这个调用为例子来分析,其它的同理.
           前面我们已经拿到了 helloService对象,它是一个Proxy(BinderProxy)对象,位于Stub内部.我们看一下它的实现
      
  
  
public int getVal() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getVal, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
          核心就是mRemote.transact(Stub.TRANSACTION_getVal, _data, _reply, 0),而此时的mRemote就是现实实例化Proxy
     的时候传入的BinderProxy对象。而 BinderProxy.transact函数是一个JNI方法,最终又到了 android_util_Binder中的
     android_os_BinderProxy_transact方法内部,此时它的code是Stub.TRANSACTION_getVal.最终和驱动去打交道,让驱动唤
     醒Helloserice的服务端的相应接口去处理我们的请求。
         而HelloService这个Server线程被唤醒之后 就会调用JavaBBinder类的onTransact函数,(由驱动实现的),这块就是服务端
    着手处理远程代理端(客户端)的JNI层的起始位置.!!!!!!!!很重要!!!!!!!
        JavaBBinder的代码实现我们已经在前面介绍过,此处再贴一下代码
   
   
 
//HelloService这个Server线程被唤醒之后,就会调用JavaBBinder类的onTransact函数!!!!!
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
{
JNIEnv* env = javavm_to_jnienv(mVM);
ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
IPCThreadState* thread_state = IPCThreadState::self();
const int32_t strict_policy_before = thread_state->getStrictModePolicy();
......
//mObject就是HelloService类的一个实例对象了,就调用了HelloService.execTransact函数
//AIDL生成的文件IHelloService.java里面并没有重写它,所以会走到Binder类中.
//注意此时实例化的是HelloService!!!(不是父类什么的)
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
jthrowable excep = env->ExceptionOccurred();
......//异常和权限的一些处理.
// Need to always call through the native implementation of
// SYSPROPS_TRANSACTION.
if (code == SYSPROPS_TRANSACTION) {
BBinder::onTransact(code, data, reply, flags);
}
//......
return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}
           HelloService实例化时,曾经介绍过,JavaBBinder类里面的成员变量mObject就是HelloService类的一个实例对象了 最
      终其实就是调用到了HelloService.execTransact函数.而我们在写自己的服务的时候一般都不回去手动重写 execTransact。但
       HelloService extends Binder.也就是调用到了Binder的 execTransact。如下:
  
  
//AIDL生成的文件IHelloService.java里面并没有重写它,所以会走到这里
// Entry point from android_util_Binder.cpp's onTransact
private boolean execTransact(int code, long dataObj, long replyObj,
int flags) {
Parcel data = Parcel.obtain(dataObj);
Parcel reply = Parcel.obtain(replyObj);
boolean res;
try {
//此时Helloservice子类,有重写就调用自己的onTransact,而public class HelloService
//extends IHelloService.Stub.所以调用到IHelloService.Stub
res = onTransact(code, data, reply, flags);
} catch (RemoteException e) {
......
} catch (RuntimeException e) {
......
} catch (OutOfMemoryError e) {
......
}
......
return res;
}
          最终调用到了HelloService的onTransact.而 HelloService并没有自己实现所以是 HelloService.Stub的.
          
  
  
@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:
......
case TRANSACTION_setVal:
......
case TRANSACTION_getVal://前面的code传入的是这个.
{
data.enforceInterface(DESCRIPTOR);
//public class HelloService extends IHelloService.Stub
//最后由于本身就是Helloservice对象在调用,
//而他又重写了这个方法,所以会调用到HelloService的具体的getVal().(完成调用).
int _result = this.getVal();
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
          至此完成调用,调用到我们写的那个HelloService里面。然后一层层的返回,返回到
          mRemote.transact(Stub.TRANSACTION_getVal, _data, _reply, 0)调用的地方。驱动的服务端处理完毕后 _reply就有值
     了然后_result = _reply.readInt();对出街过并return回去.
          这样就完成了整个的client端获取远程服务的代理对象,并调用相应的接口。总的来从应用角度来触发,作为调用端client,
     先是通过service manager的java远程接口来获取Helloservice的远程代理接口,进而调用HelloService提供的服务.

  4.5、网上整理和个人瞎扯。
          a、对aidl的作用感觉就是为了方便开发,客户端这边和服务端其实是需要沟通好的,如我的客户端的某个操作,到你服务端你
     需要解析成什么样子的,再比如说我客户端通过Binder往你那边传数据往Parcel里面写入时候的顺序等等,你那边也应该依次读取
     而AIDL就是通过工具,自动的帮我们完成一个服务端代理proxy,以及服务端存存根Stub.这两个中介在自己内部很好的解释了每
    个语义什么意思等等。而不需要在去到真正的客户端/服务端代码中去做什么特殊的处理.(拉出来放一个类里面,而这个类有系统的 
     编译脚本来根据一定的规则自动生成).
         其实这就是一种代理proxy、存根Stub的结构。client---proxy--Stub---server.   由proxy和Stub去解释进程通信间的一些规范
    问题,也实现了屏蔽进程的概念。当然在proxy和Stub之间通过Binder的机制配合Parcel的序列化和反序列化传递数据.
        b、asInterface的返回值的问题,我们分析的都是由于是跨进程调用所以传入的参数都是BinderProxy此时就会返回Stub.Proxy
   对象。而当我们是在本进程内通信的时候纯如Binder对象,此时就会直接翻会Stub类的对象。无需进行跨进程调用。
       c、对于底层的服务实现的时候都会有:
              ProcessState::self()- >startThreadPool();
              IPCThreadState::self()->joinThreadPool();
       这样就会有线程来处理client端传来的数据,但是我们在java层写服务的时候就不需要关注这些细节了,因为这个服务通过add添
       加进去以后它会运行System进程中,System进程在启动的时候会自动的启动一个Binder线程池,在System_init.cpp当中.
      d、Binder进程间通信机制中的Service组件和Android应用程序中的Service组件是两个完全不同的概念,Android应用程序中的   
            Service组件不 是一个Binder对象,即它不是Binder进制间通信机制中的Service组件的概念。 Android应用程序中的Service组件具
            有Binder进程间通信能力是因为它可以通过成 员函数onBind来返回一个Binder代理对象给调用者使用.
                 Android中对于Binder这个对象有特殊的进程通信处理机制。所以可以再进程之间来回传输携带数据等等,并不是service类就可
            以而要是binder类。
      e、binder机制整理概述。
                比如client a 想和 server b通信。client a 先通过server manager获取一个server b的一个代理接口c,注意代理接口中的方法是
           和 server中的方法一一对应的,a想要调用某个方法时,代理接口c就会把client 发过来的数据发送给内核中的binder driver。而对
           于server b端,它就回去这个binder driver中读取请求的数据进而作出相应的处理,最终通过binder driver实现了跨进程通信。
  
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值