首页 > 代码库 > android分析之Binder 02

android分析之Binder 02

分析Java层的ServiceManager,看看Binder在Java层是如何实现的。

public final class ServiceManager {    private static final String TAG = "ServiceManager";    private static IServiceManager sServiceManager;//IserviceManager是一个接口,定义了通用(公共)方法。    private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();//缓存,其值是IBinder...    public static IBinder getService(String name) {        try {            IBinder service = sCache.get(name);//先从缓存中查找            if (service != null) {                return service;            } else {                return getIServiceManager().getService(name);//生成新的IBinder            }        } catch (RemoteException e) {            Log.e(TAG, "error in getService", e);        }        return null;    }
...

  这里的ServiceManager仅仅是一种封装,其成员变量和方法都是static。从上面的sCache保存的键值对和getService的返回值类型为IBinder(与C++层的IBinder不同)可以看出,通过ServiceManager得到的是一个IBinder类型对象,通过后面的分析,实际可以看出它是BpBinder对象。

    private static IServiceManager getIServiceManager() {        if (sServiceManager != null) {            return sServiceManager;        }        // Find the service manager        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());//找到IServiceManager对象,并返回        return sServiceManager;    }...    /**     * Return the global "context object" of the system.  This is usually     * an implementation of IServiceManager, which you can use to find     * other services.     */    public static final native IBinder getContextObject();//BinderInternale:调用native函数,返回IBinder对象...    static public IServiceManager asInterface(IBinder obj)//传入的就是上面的那个IBinder对象,记住这是Java对象    {        if (obj == null) {            return null;        }        IServiceManager in =            (IServiceManager)obj.queryLocalInterface(descriptor);//从IBinder对象里查找,并转换为IServiceManager对象        if (in != null) {            return in;        }                return new ServiceManagerProxy(obj);//如果找不到,则使用传入的IBinder对象生成一个ServiceManagePorxy对象    }

  上面绕了一圈,直接从ServiceManagerProxy来看,有两方面:1,得到native层的一个某对象,并转换为IBinder,即上面的native IBinder getContextObject();2,使用获得的IBinder来生成一个ServiceManagerProxy对象。下面来看看ServiceManagerProxy的构造方法:

    public ServiceManagerProxy(IBinder remote) {        mRemote = remote;//mRemote是IBinder类型,这里将传入的IBinder对象保存在mRemote    }
    public IBinder getService(String name) throws RemoteException {        Parcel data = http://www.mamicode.com/Parcel.obtain();>

  小结:调用ServiceManager的getService(),会生成一个ServiceManagerProxy对象,该对象持有一个mRemote(IBinder),通过该mRemote(它是BpBinder在Java层的代表)可以向下层发送数据。

 

getContextObject分析:

public static final native IBinder getContextObject();//BinderInternale:调用native函数,返回IBinder对象——对应为下面这个函数:

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz){    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);//走到这里:b为一个BpBinder    return javaObjectForIBinder(env, b);//返回一个Java层的BinderProxy

  到这里明白了,上面的mRemote持有的就是BinderProxy对象。而上面调用mRemote对象的transact()方法就是调用BinderProxy的transact方法:

    public native boolean transact(int code, Parcel data, Parcel reply,            int flags) throws RemoteException;...static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,        jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException{    if (dataObj == NULL) {        jniThrowNullPointerException(env, NULL);        return JNI_FALSE;    }    Parcel* data = http://www.mamicode.com/parcelForJavaObject(env, dataObj);>...
  status_t err = target->transact(code, *data, reply, flags);//调用BpBinder来与更下层通信...

  走到这里:Java层主要就是获取Native层的BpBinder,并使用它来与下层通信。

 

android分析之Binder 02