1. Framework 层的 JNI 函数封装
Framework 对常用的 JNI 函数做了封装:
namespace android {
//查找对应Java类
static inline jclass FindClassOrDie(JNIEnv* env, const char* class_name) {
jclass clazz = env->FindClass(class_name);
LOG_ALWAYS_FATAL_IF(clazz == NULL, "Unable to find class %s", class_name);
return clazz;
}
//返回类的实例域 ID
static inline jfieldID GetFieldIDOrDie(JNIEnv* env, jclass clazz, const char* field_name,
const char* field_signature) {
jfieldID res = env->GetFieldID(clazz, field_name, field_signature);
LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find static field %s", field_name);
return res;
}
//返回 Java 类或者接口实例非静态方法的方法 ID
static inline jmethodID GetMethodIDOrDie(JNIEnv* env, jclass clazz, const char* method_name,
const char* method_signature) {
jmethodID res = env->GetMethodID(clazz, method_name, method_signature);
LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find method %s", method_name);
return res;
}
//返回类的静态域的属性 ID
static inline jfieldID GetStaticFieldIDOrDie(JNIEnv* env, jclass clazz, const char* field_name,
const char* field_signature) {
jfieldID res = env->GetStaticFieldID(clazz, field_name, field_signature);
LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find static field %s", field_name);
return res;
}
//返回类的静态方法 ID
static inline jmethodID GetStaticMethodIDOrDie(JNIEnv* env, jclass clazz, const char* method_name,
const char* method_signature) {
jmethodID res = env->GetStaticMethodID(clazz, method_name, method_signature);
LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find static method %s", method_name);
return res;
}
//基于局部引用创建一个全局引用
template <typename T>
static inline T MakeGlobalRefOrDie(JNIEnv* env, T in) {
jobject res = env->NewGlobalRef(in);
LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to create global reference.");
return static_cast<T>(res);
}
//注册 Java 类对应的 JNI 方法
static inline int RegisterMethodsOrDie(JNIEnv* env, const char* className,
const JNINativeMethod* gMethods, int numMethods) {
int res = AndroidRuntime::registerNativeMethods(env, className, gMethods, numMethods);
LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
return res;
}
/**
* Read the specified field from jobject, and convert to std::string.
* If the field cannot be obtained, return defaultValue.
*/
static inline std::string getStringField(JNIEnv* env, jobject obj, jfieldID fieldId,
const char* defaultValue) {
ScopedLocalRef<jstring> strObj(env, jstring(env->GetObjectField(obj, fieldId)));
if (strObj != nullptr) {
ScopedUtfChars chars(env, strObj.get());
return std::string(chars.c_str());
}
return std::string(defaultValue);
}
} // namespace android
#endif // CORE_JNI_HELPERS
上述封装中涉及到了 LOG_ALWAYS_FATAL_IF 宏,该宏用于记录一个致命错误。如果给定的条件失败,这将停止程序。像普通断言一样执行,但会生成给定的消息。该功能不会从 release 版本中剥离。需要注意的是,条件测试与正常的 assert() 语义相反。
FindClass,GetFieldID,NewGlobalRef
等 JNI 函数在调用过程中都可能发生异常,我们在[JNI 编程上手指南之异常处理]()中介绍了处理这类异常的一般手法,framework 中的处理稍有不同,当出现异常时,直接通过 LOG_ALWAYS_FATAL_IF 宏中断程序。
2. Java 层初始化
Android Zygote 启动时,会调用 AndroidRuntime::startReg
注册一系列的 JNI 方法,其中包含了 Java 层与 Binder 相关的 JNI 方法:
// frameworks/base/core/jni/AndroidRuntime.cpp
static const RegJNIRec gRegJNI[] = {
//...
REG_JNI(register_android_os_Binder),
//...
}
int AndroidRuntime::startReg(JNIEnv* env)
{
//......
//注册 jni 函数
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
env->PopLocalFrame(NULL);
return -1;
}
//......
return 0;
}
上面的代码注册了一系列的 JNI 方法,其中 gRegJNI 是一个数组,保存了一系列的待注册的 JNI 方法列表, 其中的 register_android_os_Binder 就是与 Binder 的 JNI 函数注册相关的。
register_android_os_Binder 是一个函数指针,我们来看一下它的具体实现:
// frameworks/base/core/jni/android_util_Binder.cpp
int register_android_os_Binder(JNIEnv* env)
{
//注册 Binder 类的 JNI 方法
if (int_register_android_os_Binder(env) < 0)
return -1;
//注册 BinderInteral 类的 JNI 方法
if (int_register_android_os_BinderInternal(env) < 0)
return -1;
//注册 BinderProxy 类的 JNI 方法
if (int_register_android_os_BinderProxy(env) < 0)
return -1;
//......
return 0;
}
这里依次调用了三个方法来注册 JNI 方法,我们以第一个为例来分析:
static int int_register_android_os_Binder(JNIEnv* env)
{
jclass clazz = FindClassOrDie(env, kBinderPathName);
gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
gBinderOffsets.mGetInterfaceDescriptor = GetMethodIDOrDie(env, clazz, "getInterfaceDescriptor",
"()Ljava/lang/String;");
gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
return RegisterMethodsOrDie(
env, kBinderPathName,
gBinderMethods, NELEM(gBinderMethods));
}
//函数涉及到的其他变量
static const JNINativeMethod gBinderMethods[] = {
{ "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
{ "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
{ "isHandlingTransaction", "()Z", (void*)android_os_Binder_isHandlingTransaction },
{ "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
{ "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
{ "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
{ "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
{ "setCallingWorkSourceUid", "(I)J", (void*)android_os_Binder_setCallingWorkSourceUid },
{ "getCallingWorkSourceUid", "()I", (void*)android_os_Binder_getCallingWorkSourceUid },
{ "clearCallingWorkSource", "()J", (void*)android_os_Binder_clearCallingWorkSource },
{ "restoreCallingWorkSource", "(J)V", (void*)android_os_Binder_restoreCallingWorkSource },
{ "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
{ "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
{ "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
{ "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
};
static struct bindernative_offsets_t
{
// Class state.
jclass mClass;
jmethodID mExecTransact;
jmethodID mGetInterfaceDescriptor;
// Object state.
jfieldID mObject;
} gBinderOffsets;
const char* const kBinderPathName = "android/os/Binder";
int_register_android_os_Binder
的操作很简单,就是把 android/os/Binder
的部分成员 ID 保存到全局结构体变量 gBinderOffsets 中,这么做的原因我们在[JNI 编程上手指南之 JNI 调用性能优化]() 中说过,主要是为了提高 JNI 调用的性能。最后再调用 RegisterMethodsOrDie
将 gBinderMethods
数组中的函数注册到 JVM,这样 android/os/Binder
中定义的 Native 方法才能正常调用。
另外两个函数 int_register_android_os_BinderInternal
和 int_register_android_os_BinderProxy
的执行流程基本是一模一样。留给读者自行分析。
总结
通过上面的分析我们应该知道, Java 层中的三个类 BinderProxy BinderInternal Binder 是在 zygote 中启动一个新进程,初始化 JVM 环境时注册的 Native 方法,当执行到这三个类的 Native 方法时,我们应该到 frameworks/base/core/jni/android_util_Binder.cpp
文件中去查看其 Native 实现。
注册过程分析
1. Java 层整体框架
在分析之前,我们要明白,Java 只是一层方便 Java 程序使用的接口,Binder 的核心功能实现都是通过 JNI 调用到 Native 层来实现的,这里先给出 Java 层的整体框架图:
接下来几篇文章我们逐步分析,解密整张框架图。
2. 服务注册
在 [Binder 程序示例之 Java 篇]() 中介绍的示例程序中,Server 端我们使用如下代码注册我们定义的服务:
ServiceManager.addService("hello", new HelloService());
addService 是 frameworks/base/core/java/android/os/ServiceManager.java
中定义的静态方法:
@UnsupportedAppUsage
public static void addService(String name, IBinder service) {
addService(name, service, false, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
}
@UnsupportedAppUsage
public static void addService(String name, IBinder service, boolean allowIsolated) {
addService(name, service, allowIsolated, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
}
@UnsupportedAppUsage
public static void addService(String name, IBinder service, boolean allowIsolated,int dumpPriority) {
try {
getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
通过层层调用,调用到 getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
:
2.1 getIServiceManager()
我们先看看 getIServiceManager,该方法是定义在 ServiceManager 类中的静态方法:
//frameworks/base/core/java/android/os/ServiceManager.java
@UnsupportedAppUsage
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// 等价于 new ServiceManagerProxy(new BinderProxy(0))
// 但是实际过程有点曲折
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
接着我们逐一分析三个方法调用:
BinderInternal.getContextObject()
Binder.allowBlocking
ServiceManagerNative.asInterface
2.1.1 BinderInternal.getContextObject
//frameworks/base/core/java/com/android/internal/os/BinderInternal.java
// 返回一个 BinderProxy 对象
@UnsupportedAppUsage
public static final native IBinder getContextObject();
getContextObject
是一个 native 方法,在之前的文章中我们提到 BinderInternal 在进程启动时注册了其 native 方法,其 native 实现在 frameworks/base/core/jni/android_util_Binder.cpp
中:
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
//此处返回的是 new BpBinder(0)
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
//此处返回的是 new BinderProxy()
return javaObjectForIBinder(env, b);
}
接着看 getContextObject 的实现:
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
return getStrongProxyForHandle(0);
}
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
handle_entry* e = lookupHandleLocked(handle);
if (e != nullptr) {
IBinder* b = e->binder;
if (b == nullptr || !e->refs->attemptIncWeak(this)) {
if (handle == 0) {
Parcel data;
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, nullptr, 0);
if (status == DEAD_OBJECT)
return nullptr;
}
//走这里
b = BpBinder::create(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
BpBinder* BpBinder::create(int32_t handle) {
int32_t trackedUid = -1;
if (sCountByUidEnabled) {
trackedUid = IPCThreadState::self()->getCallingUid();
AutoMutex _l(sTrackingLock);
uint32_t trackedValue = sTrackingMap[trackedUid];
if (CC_UNLIKELY(trackedValue & LIMIT_REACHED_MASK)) {
if (sBinderProxyThrottleCreate) {
return nullptr;
}
} else {
if ((trackedValue & COUNTING_VALUE_MASK) >= sBinderProxyCountHighWatermark) {
ALOGE("Too many binder proxy objects sent to uid %d from uid %d (%d proxies held)",
getuid(), trackedUid, trackedValue);
sTrackingMap[trackedUid] |= LIMIT_REACHED_MASK;
if (sLimitCallback) sLimitCallback(trackedUid);
if (sBinderProxyThrottleCreate) {
ALOGI("Throttling binder proxy creates from uid %d in uid %d until binder proxy"
" count drops below %d",
trackedUid, getuid(), sBinderProxyCountLowWatermark);
return nullptr;
}
}
}
sTrackingMap[trackedUid]++;
}
//走这里
return new BpBinder(handle, trackedUid);
}
代码看着很繁琐,实际流程其实很简单就是 new BpBinder(0)
。
接着看 javaObjectForIBinder
的实现:
//frameworks/base/core/jni/android_util_Binder.cpp
//当前情景下, val 的类型是 BpBinder
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
if (val == NULL) return NULL;
if (val->checkSubclass(&gBinderOffsets)) {
// It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
jobject object = static_cast<JavaBBinder*>(val.get())->object();
LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
return object;
}
//构造 BinderProxyNativeData 结构体
BinderProxyNativeData* nativeData = new BinderProxyNativeData();
nativeData->mOrgue = new DeathRecipientList;
nativeData->mObject = val;
//gBinderProxyOffsets 中保存了 BinderProxy 类相关的信息
//调用 Java 层 GetInstance 方法获得一个 BinderProxy 对象
jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
if (env->ExceptionCheck()) { //异常处理
// In the exception case, getInstance still took ownership of nativeData.
return NULL;
}
BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
if (actualNativeData == nativeData) {
// Created a new Proxy
uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed);
uint32_t numLastWarned = gProxiesWarned.load(std::memory_order_relaxed);
if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) {
// Multiple threads can get here, make sure only one of them gets to
// update the warn counter.
if (gProxiesWarned.compare_exchange_strong(numLastWarned,
numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) {
ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies);
}
}
} else {
delete nativeData;
}
//返回 BinderProxy
return object;
}
native 代码调用了 BinderProxy 的 getInstance 方法:
// frameworks/base/core/java/android/os/BinderProxy.java
private static BinderProxy getInstance(long nativeData, long iBinder) {
BinderProxy result;
synchronized (sProxyMap) {
try {
result = sProxyMap.get(iBinder);
if (result != null) {
return result;
}
result = new BinderProxy(nativeData);
} catch (Throwable e) {
// We're throwing an exception (probably OOME); don't drop nativeData.
NativeAllocationRegistry.applyFreeFunction(NoImagePreloadHolder.sNativeFinalizer,
nativeData);
throw e;
}
NoImagePreloadHolder.sRegistry.registerNativeAllocation(result, nativeData);
// The registry now owns nativeData, even if registration threw an exception.
sProxyMap.set(iBinder, result);
}
return result;
}
代码很繁琐,但是从结果上来说还是比较简单的:
- getContextObject 函数 new 了一个 BpBinder(c++结构体),其内部的 handle 是 0
- javaObjectForIBinder 函数 new 了一个 BinderProxy(Java 对象),其内部成员 mNativeData 是一个 native 层指针,指向一个 BinderProxyNativeData,BinderProxyNativeData 的成员 mObject 指向上述的 BpBinder。
整体结构用一个图表示如下:
2.1.2 Binder.allowBlocking
//这里传入的是 BinderProxy 对象
public static IBinder allowBlocking(IBinder binder) {
try {
if (binder instanceof BinderProxy) { //走这里
((BinderProxy) binder).mWarnOnBlocking = false;
} else if (binder != null && binder.getInterfaceDescriptor() != null
&& binder.queryLocalInterface(binder.getInterfaceDescriptor()) == null) {
Log.w(TAG, "Unable to allow blocking on interface " + binder);
}
} catch (RemoteException ignored) {
}
return binder;
}
这个方法比较简单,主要是设置 binder 的成员变量 mWarnOnBlocking 为 false。从名字来看,作用是允许阻塞调用。
2.1.3 ServiceManagerNative.asInterface
//frameworks/base/core/java/android/os/ServiceManagerNative.java
//传入的参数是 BinderProxy
@UnsupportedAppUsage
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
//返回 null
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
//走这里,构建一个 ServiceManagerProxy
return new ServiceManagerProxy(obj);
}
//从名字来看,本来要做缓存的,但是没有做
// frameworks/base/core/java/android/os/BinderProxy.java
public IInterface queryLocalInterface(String descriptor) {
return null;
}
最终是构建一个 ServiceManagerProxy 结构体。其内部持有一个 BinderProxy 。
至此,getIServiceManager
的整体流程就分析完了。
2.2 addService
// frameworks/base/core/java/android/os/ServiceManagerNative.java
public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
data.writeInt(dumpPriority);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
构造两个 Parcel 结构,然后调用 mRemote.transact
发起远程过程调用。
mRemote 就是 new ServiceManagerProxy 时传入的 BinderProxy:
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
进入 frameworks/base/core/java/android/os/BinderProxy.java
查看:
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
//......
try {
//关注这里
return transactNative(code, data, reply, flags);
} finally {
//......
}
}
//native 方法
public native boolean transactNative(int code, Parcel data, Parcel reply,int flags) throws RemoteException;
transact 会调用 transactNative 发起远程调用,transactNative 是一个 native 方法,具体实现在 frameworks/base/core/jni/android_util_Binder.cpp
:
// obj 对应类型为 BinderProxy
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;
}
// Java 对象 转为 c++ 对象
Parcel* data = parcelForJavaObject(env, dataObj);
if (data == NULL) {
return JNI_FALSE;
}
// Java 对象 转为 c++ 对象
Parcel* reply = parcelForJavaObject(env, replyObj);
if (reply == NULL && replyObj != NULL) {
return JNI_FALSE;
}
//拿到 BinderProxyNativeData 成员的 mObject,实际是一个 BpBinder
IBinder* target = getBPNativeData(env, obj)->mObject.get();
if (target == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
return JNI_FALSE;
}
ALOGV("Java code calling transact on %p in Java object %p with code %" PRId32 "\n",
target, obj, code);
bool time_binder_calls;
int64_t start_millis;
if (kEnableBinderSample) {
// Only log the binder call duration for things on the Java-level main thread.
// But if we don't
time_binder_calls = should_time_binder_calls();
if (time_binder_calls) {
start_millis = uptimeMillis();
}
}
//BpBinder 发起远程调用
status_t err = target->transact(code, *data, reply, flags);
if (kEnableBinderSample) {
if (time_binder_calls) {
conditionally_log_binder_call(start_millis, target, code);
}
}
if (err == NO_ERROR) {
return JNI_TRUE;
} else if (err == UNKNOWN_TRANSACTION) {
return JNI_FALSE;
}
signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
return JNI_FALSE;
}
可以看出,绕了一圈还是通过 native 层的 BpBinder 发起远程调用,native 层的调用过程可以参考之前的文章[Binder 服务注册过程情景分析之 C++ 篇]
服务获取过程
在 [Binder 程序示例之 Java 篇]() 中我们介绍了,Client 通过以下代码获取到服务:
IBinder binder = ServiceManager.getService("hello");
IHelloService svr = IHelloService.Stub.asInterface(binder);
// frameworks/base/core/java/android/os/ServiceManager.java
@UnsupportedAppUsage
private static Map<String, IBinder> sCache = new ArrayMap<String, IBinder>();
@UnsupportedAppUsage
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return Binder.allowBlocking(rawGetService(name));
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
private static IBinder rawGetService(String name) throws RemoteException {
final long start = sStatLogger.getTime();
// getIServiceManager() 等价于 new ServiceManagerProxy(new BinderProxy(0))
final IBinder binder = getIServiceManager().getService(name);
final int time = (int) sStatLogger.logDurationStat(Stats.GET_SERVICE, start);
final int myUid = Process.myUid();
final boolean isCore = UserHandle.isCore(myUid);
final long slowThreshold = isCore
? GET_SERVICE_SLOW_THRESHOLD_US_CORE
: GET_SERVICE_SLOW_THRESHOLD_US_NON_CORE;
synchronized (sLock) {
sGetServiceAccumulatedUs += time;
sGetServiceAccumulatedCallCount++;
final long nowUptime = SystemClock.uptimeMillis();
// Was a slow call?
if (time >= slowThreshold) {
// We do a slow log:
// - At most once in every SLOW_LOG_INTERVAL_MS
// - OR it was slower than the previously logged slow call.
if ((nowUptime > (sLastSlowLogUptime + SLOW_LOG_INTERVAL_MS))
|| (sLastSlowLogActualTime < time)) {
EventLogTags.writeServiceManagerSlow(time / 1000, name);
sLastSlowLogUptime = nowUptime;
sLastSlowLogActualTime = time;
}
}
// Every GET_SERVICE_LOG_EVERY_CALLS calls, log the total time spent in getService().
final int logInterval = isCore
? GET_SERVICE_LOG_EVERY_CALLS_CORE
: GET_SERVICE_LOG_EVERY_CALLS_NON_CORE;
if ((sGetServiceAccumulatedCallCount >= logInterval)
&& (nowUptime >= (sLastStatsLogUptime + STATS_LOG_INTERVAL_MS))) {
EventLogTags.writeServiceManagerStats(
sGetServiceAccumulatedCallCount, // Total # of getService() calls.
sGetServiceAccumulatedUs / 1000, // Total time spent in getService() calls.
(int) (nowUptime - sLastStatsLogUptime)); // Uptime duration since last log.
sGetServiceAccumulatedCallCount = 0;
sGetServiceAccumulatedUs = 0;
sLastStatsLogUptime = nowUptime;
}
}
return binder;
}
@UnsupportedAppUsage
public IBinder getService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
//BinderProxy 的 transact
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
//......
try {
//关注这里
return transactNative(code, data, reply, flags);
} finally {
//......
}
}
//native 方法
public native boolean transactNative(int code, Parcel data, Parcel reply,int flags) throws RemoteException;
transact 会调用 transactNative 发起远程调用,transactNative 是一个 native 方法,具体实现在 frameworks/base/core/jni/android_util_Binder.cpp
:
// obj 对应类型为 BinderProxy
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;
}
// Java 对象 转为 c++ 对象
Parcel* data = parcelForJavaObject(env, dataObj);
if (data == NULL) {
return JNI_FALSE;
}
// Java 对象 转为 c++ 对象
Parcel* reply = parcelForJavaObject(env, replyObj);
if (reply == NULL && replyObj != NULL) {
return JNI_FALSE;
}
//拿到 BinderProxyNativeData 成员的 mObject,实际是一个 BpBinder
IBinder* target = getBPNativeData(env, obj)->mObject.get();
if (target == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
return JNI_FALSE;
}
ALOGV("Java code calling transact on %p in Java object %p with code %" PRId32 "\n",
target, obj, code);
bool time_binder_calls;
int64_t start_millis;
if (kEnableBinderSample) {
// Only log the binder call duration for things on the Java-level main thread.
// But if we don't
time_binder_calls = should_time_binder_calls();
if (time_binder_calls) {
start_millis = uptimeMillis();
}
}
//BpBinder 发起远程调用
status_t err = target->transact(code, *data, reply, flags);
if (kEnableBinderSample) {
if (time_binder_calls) {
conditionally_log_binder_call(start_millis, target, code);
}
}
if (err == NO_ERROR) {
return JNI_TRUE;
} else if (err == UNKNOWN_TRANSACTION) {
return JNI_FALSE;
}
signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
return JNI_FALSE;
}
可以看出,绕了一圈还是通过 native 层的 BpBinder 发起远程调用,native 层的调用过程可以参考之前的文章[Binder 服务注册过程情景分析之 C++ 篇]()
服务使用过程
svr.sayhello();
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/20593,转载请注明出处。
评论0