1,应用程序只需要调用ServiceManager.getService(name)就可以获取到获取到相应的服务
/**
* Returns a reference to a service with the given name.
*
* @param name the name of the service to get
* @return a reference to the service, or null
if the service doesn't exist
*/
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return Binder.allowBlocking(getIServiceManager().getService(name));
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
先从缓存中去翻阅历史记录,如果缓存中有就直接返回,如果没有就调用getIServiceManager().getService(name)发起一条查询请求。
2,getIServiceManager()会获取到一个IServiceManager的接口对象
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
为了防止多次创建IServiceManager对象,会做一个非空判断,如果为空才会调用ServiceManagerNative的asInterface获取一个IServiceManager对象.传入的参数是个binder对象。
3,接着看asInterface的实现
/**
* Cast a Binder object into a service manager interface, generating
* a proxy if needed.
*/
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);
}
可以J看到方法上面有一行注释,意思是将Binder对象转换为服务管理器接口,生成
*代理(如果需要)。也就是将BInder对象转化为IServiceManager对象。
该方法首先会调用queryLocalInterface去查询本地是否已经有IServiceManager,如果没有也就是返回值为null就会创建一个
ServiceManagerProxy 对象,可以肯定ServiceManagerProxy 肯定实现了IServiceManager这个接口。
4,接着看ServiceManagerProxy的构造方法是如何实现的
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
可以看到,ServiceManagerProxy没有做任何事情,只是将这个Binder对象保存起来了。
如果客户端想要获取各种服务端的binder,只需要调用ServiceManagerProxy中的getService就可以获取到各种服务端的biner句柄,然后就可以操作服务端的相关业务了,如下:
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 binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
可以看到getService主要做了如下事情:
a,使用Parcel对象打包数据
b,调用Binder的transact方法发送数据
c,获取返回结果
整个过程最重要的一个方法就是transact方法,启动里面有一个参数GET_SERVICE_TRANSACTION
在Ibinder中定义:
/**
* The first transaction code available for user commands.
*/
int FIRST_CALL_TRANSACTION = 0x00000001;
业务代码是1,在服务端定义的业务代码也是1这样服务端和客户端就对应起来了
enum {
/* Must match definitions in IBinder.h and IServiceManager.h */
PING_TRANSACTION = B_PACK_CHARS('_','P','N','G'),
SVC_MGR_GET_SERVICE = 1,
SVC_MGR_CHECK_SERVICE,
SVC_MGR_ADD_SERVICE,
SVC_MGR_LIST_SERVICES,
};
5,最开始我们获取getService的时候然后一直到创建ServiceManagerProxy对象的时候一直有个Biner对象贯穿其中,这样我们才能最终调用transact方法与服务端进行通信,那么这个Biner是怎么来的呢?
可以看到最开始是调用BinderInternal.getContextObject() 传入了asInterface接口。
6,继续分析这个方法
,
/**
* 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();
跟踪代码发现这是一个native方法
而切注释是这样说的:
返回系统的全局“上下文对象”。 通常是IserviceManager的实现,可用于查找其他服务.
7,接着看改方法的native层实现
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
可以看到使用ProcessState实现的
其中ProcessState::self()->getContextObject 返回的是一个native层的biner对象,也就是BpBinder,而BpBiner实现了native层IBiner接口 。BinderProxy实现了java层的IBiner接口。
其中javaObjectForIBinder是将一个BpBinder转化为BinderProxy,也就是将native层的biner代理对象转化java层的代理对象。
最后才将biner返回到java层。
说白了BinderInternal.getContextObject()其实拿到的其是一个native层的biner对象,中间通过jni的调用转换成了java层的binder也就是BinderProxy.
拿到这个java层的binder对象干什么用能,其实就是为了调用java层的中binder的transact方法,当然说的有点绝对了,肯定还做了其他的事。然后我们又回到了之前分析的transact方法。
8,继续分析之前的tranct方法.
根据之前的分析BinderInternal.getContextObject()反会的是一个实现了IBinder接口的BinderProxy对象,最后传给了ServiceManagerProxy,然后getService的时候调用了transact方法。所以我们接着分析BinderProxy的transact方法
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
if (mWarnOnBlocking && ((flags & FLAG_ONEWAY) == 0)) {
// For now, avoid spamming the log by disabling after we've logged
// about this interface at least once
mWarnOnBlocking = false;
Log.w(Binder.TAG, "Outgoing transactions from this process must be FLAG_ONEWAY",
new Throwable());
}
final boolean tracingEnabled = Binder.isTracingEnabled();
if (tracingEnabled) {
final Throwable tr = new Throwable();
Binder.getTransactionTracker().addTrace(tr);
StackTraceElement stackTraceElement = tr.getStackTrace()[1];
Trace.traceBegin(Trace.TRACE_TAG_ALWAYS,
stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName());
}
try {
return transactNative(code, data, reply, flags);
} finally {
if (tracingEnabled) {
Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
}
}
}
可以看到最终还是调用到了native层的transactNative方法
接着看 frameworks\base\core\jni\android_util_Binder.cpp
static const JNINativeMethod gBinderProxyMethods[] = {
/* name, signature, funcPtr */
{"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
{"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
{"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
{"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
{"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
{"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
{"destroy", "()V", (void*)android_os_BinderProxy_destroy},
};
通过android_util_Binder.cpp中的jni注册函数看,java层transactNative方法对应的是android_os_BinderProxy_transact这个方法
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*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
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();
}
}
//printf("Transact from Java code to %p sending: ", target); data->print();
status_t err = target->transact(code, *data, reply, flags);
//if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
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;
}
通过这一行代码 status_t err = target->transact(code, *data, reply, flags);发现
最终调用的了到了native层BpBinder.cpp里面的transact函数。根据前面的分析,之前是将native层的Bpbiner对象转化为java层的
BinderProxy对象,在这个方法里面肯定要转换回去,不然怎么调用native层的transact函数。
其中的 gBinderProxyOffsets.mObject记录的是native层的对象对象属性id,然后就可以通过GetLongField获取这个对象的内存地址了。接着就可以通过这个指针调用c层的transact方法:
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
然后用到了IPCThreadState.
整个过程最重要的就是如Binder的native层的biner代理的和java层的binder代理的互相转化,比较深层次的进程通信还未说道。
重点就要关注ProcessState和IPCThreadState这两个类,以后待分析