博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android分析之Binder 02
阅读量:7113 次
发布时间:2019-06-28

本文共 4231 字,大约阅读时间需要 14 分钟。

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

public final class ServiceManager {    private static final String TAG = "ServiceManager";    private static IServiceManager sServiceManager;//IserviceManager是一个接口,定义了通用(公共)方法。    private static HashMap
sCache = new HashMap
();//缓存,其值是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 = Parcel.obtain();        Parcel reply = Parcel.obtain();        data.writeInterfaceToken(IServiceManager.descriptor);        data.writeString(name);        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);//最后使用IBinder的transact来传送数据        IBinder binder = reply.readStrongBinder();        reply.recycle();        data.recycle();        return binder;    }

  小结:调用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
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 = parcelForJavaObject(env, dataObj);    if (data == NULL) {        return JNI_FALSE;    }    Parcel* reply = parcelForJavaObject(env, replyObj);    if (reply == NULL && replyObj != NULL) {        return JNI_FALSE;    }    IBinder* target = (IBinder*)//将BinderProxy转换为BpBinder        env->GetIntField(obj, gBinderProxyOffsets.mObject); ...   status_t err = target->transact(code, *data, reply, flags);//调用BpBinder来与更下层通信...

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

 

转载于:https://www.cnblogs.com/littlefishxu/p/4003445.html

你可能感兴趣的文章
2015年7月19日21:12:13 学习手册
查看>>
升级Android SDK后ADT找不到adb.exe文件的解决办法(转)
查看>>
C# & OR &&
查看>>
NAT和桥接的区别
查看>>
查看进程
查看>>
织梦的autoindex和intemindex的区别
查看>>
标准W3C盒子模型和IE盒子模型CSS布局经典盒子模型
查看>>
开源USM-AlienVault OSSIM
查看>>
Linux系统单用户模式
查看>>
android 中MVC与MVP,MVVM模式使用介绍
查看>>
lol skl
查看>>
postgreSQL 9.1 的安装、基本配置、简单使用
查看>>
JavaScript日期时间对象的创建与使用(三)
查看>>
PHP编程效率的20个要点
查看>>
HTC A510C屏幕失灵补丁
查看>>
mysql主从数据不一致问题解决
查看>>
go 入门学习笔记之 条件判断 if switch (七)
查看>>
Linux下清空用户登录记录和命令历史的方法
查看>>
python 函数
查看>>
Visual Sudio 复制窗体文件
查看>>