分析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 = 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<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 = 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,并使用它来与下层通信。

android分析之Binder 02的更多相关文章

  1. android分析之Binder 01

    终于还是得写一篇关于Binder的文章了.从最初接触Android到花大把时间研究Android源码,Binder一直是分析道路的拦路虎.看了几本最流行的Android源码分析书籍,每次基本上都不能把 ...

  2. Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6642463 在前面几篇文章中,我们详细介绍了A ...

  3. 098 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 02 案例分析及实现 02 编写并测试Subject类

    098 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 02 案例分析及实现 02 编写并测试Subject类 本文知识点:编写并测试Subject类 说明: ...

  4. 099 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 02 案例分析及实现 03 编写并测试Student类

    099 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 02 案例分析及实现 03 编写并测试Student类 本文知识点:编写并测试Subject类 说明: ...

  5. 101 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 02 案例分析及实现 05 通过方法实现学生类与专业类关联——方案二

    101 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 02 案例分析及实现 05 通过方法实现学生类与专业类关联--方案二 本文知识点:通过方法实现学生类与 ...

  6. Android深入浅出之Binder机制(转)

    Android深入浅出之Binder机制 一 说明 Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的.所以搞明白B ...

  7. Android IPC机制—Binder的工作机制

    进程和线程的关系 IPC机制即为跨进程通信,是inter-Process Communication的缩写.是指两个进程之间进行通信.在说进程通信之前,我们的弄明白什么是线程,什么是进程.进程和线程是 ...

  8. 从AIDL开始谈Android进程间Binder通信机制

    转自: http://tech.cnnetsec.com/585.html 本文首先概述了Android的进程间通信的Binder机制,然后结合一个AIDL的例子,对Binder机制进行了解析. 概述 ...

  9. [Android进阶]Binder学习(初始篇)

    Android中Binder学习(初始篇) 本篇博客学习自侯亮的博客.地址为: 红茶一杯话Binder 1 什么是Binder? 简单地说.Binder是Android平台上的一种跨进程交互技术. 该 ...

随机推荐

  1. MySQL 回表查询 & 索引覆盖优化

    回表查询 先通过普通索引的值定位聚簇索引值,再通过聚簇索引的值定位行记录数据 建表示例 mysql> create table user( -> id int(10) auto_incre ...

  2. leetcode28 strstr kmp bm sunday

    字符串匹配有KMP,BM,SUNDAY算法. 可见(https://leetcode-cn.com/problems/implement-strstr/solution/c5chong-jie-fa- ...

  3. leetcode15 三数之和 双指针

    注意题目没要求数字只能用一次 a + b + c = 0 即为 -b=a+c,同时要求数字不全为正(然后发现a+b+c就行...不过多想想没坏处嘛) 先处理特殊情况,然后 先排序 注意不重复,只需要有 ...

  4. javascript和XML

    一,浏览器对XML DOM的支持1,DOM2级核心 var xmldom = document.implementation.createDocument("","roo ...

  5. Gym102361A Angle Beats(直角三角形 计算几何)题解

    题意: \(n\)个点,\(q\)个询问,每次问包含询问点的直角三角形有几个 思路: 代码: #include<bits/stdc++.h> using namespace std; co ...

  6. Github access token

    Github access token https://github.com/settings/tokens https://docs.github.com/en/free-pro-team@late ...

  7. O&#178; & O₂

    O² & O₂ special symbol O² & O₂ HTML HTML subscript and superscript Tags HTML 下标元素 HTML 上标元素 ...

  8. @bind decorator

    @bind decorator https://www.npmjs.com/package/bind-decorator https://github.com/NoHomey/bind-decorat ...

  9. Learn-JavaScript-with-MDN 系列文章: 01. var & let & const 对比

    Learn-JavaScript-with-MDN 系列文章: 01. var & let & const 对比 var & let & const 区别 https: ...

  10. Linux & SIGUSER1

    Linux & SIGUSER1 https://stackoverflow.com/questions/10824886/how-to-signal-an-application-witho ...