世界发展这么快,养尊处优的你跟的上吗?
我们知道android中有很多服务进程,在面向对象的今天,如果我们想和服务进程通过Binder来通信,那么我们要持有一些类,抛开业务层的通信不讲,基础的通信层的类有在客户端这边的BpBinder,服务这边的BBinder,当然这是C++层的代码,我们还知道jni把java程序员和c++程序员聚集在了一个圆桌上,我想今天试着把它们之间的“福利合照”公开一下。
可能是c++层的类影响了java层的类,无独有偶,java通信层的类有:BinderProxy,Binder。
按照我们的使用服务的流程,在ACtivity中使用:
getSystemService(String name)
调至:
mBase.getSystemService(String name) ;
mBase是ContextImpl类型,所以:
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
而:
final class SystemServiceRegistry {
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new HashMap<String, ServiceFetcher<?>>();
private SystemServiceRegistry() { }
static {
......
registerService(Context.ACCOUNT_SERVICE, AccountManager.class,
new CachedServiceFetcher<AccountManager>() {
@Override
public AccountManager createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(Context.ACCOUNT_SERVICE);
IAccountManager service = IAccountManager.Stub.asInterface(b);
return new AccountManager(ctx, service);
}});
registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
new CachedServiceFetcher<ActivityManager>() {
@Override
public ActivityManager createService(ContextImpl ctx) {
return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
}});
registerService(Context.ALARM_SERVICE, AlarmManager.class,
new CachedServiceFetcher<AlarmManager>() {
@Override
public AlarmManager createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(Context.ALARM_SERVICE);
IAlarmManager service = IAlarmManager.Stub.asInterface(b);
return new AlarmManager(service, ctx);
}});
......
}
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
}
这些在上下文中的服务在静态代码块中初始化,这些服务大致的初始化方式分为2种。
第一种类似于ActivityManager这种,直接创建:
new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
第二种类似于AlarmManager这种,先从ServiceManager里面获取一个IBinder,再创建:
IBinder b = ServiceManager.getService(Context.ALARM_SERVICE);
IAlarmManager service = IAlarmManager.Stub.asInterface(b);
return new AlarmManager(service, ctx);
先看第一种服务的服务接口,例如:ActivityManager的getRecentTasks(int maxNum, int flags)方法:
public List<RecentTaskInfo> getRecentTasks(int maxNum, int flags)
throws SecurityException {
try {
return ActivityManagerNative.getDefault().getRecentTasks(maxNum,
flags, UserHandle.myUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
ActivityManagerNative.getDefault()调至:
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
从create方法看到,其实就明白了,第一种创建的和第二种创建的服务,使用接口的时候,都是先:
IBinder b = ServiceManager.getService(servicename);
然后:
IXXXService service = (IXXXService.Stub.)asInterface(b);
最后拿着IXXXService去调用业务层的接口,只是在创建的时候,代码的位置不一样。
所以我们先来看ServiceManager.getService(servicename)是怎么把Binder Something in Java and in C++“合照”起来的。如下:
public final class ServiceManager {
private static final String TAG = "ServiceManager";
private static IServiceManager sServiceManager;
private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
/**
* 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 <code>null</code> 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 getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
//.......
}
先关注:BinderInternal.getContextObject():
public class BinderInternal {
。。。。。。
/**
84 * Return the global "context object" of the system. This is usually
85 * an implementation of IServiceManager, which you can use to find
86 * other services.
87 */
88 public static final native IBinder getContextObject();
。。。。。。
}
调至c++层的/frameworks/base/core/jni/android_util_Binder.cpp中:
899static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
900{
901 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
902 return javaObjectForIBinder(env, b);
903}
调至ProcessState.cpp中的getContextObject:
85sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
86{
87 return getStrongProxyForHandle(0);
88}
236wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
237{
238 wp<IBinder> result;
239
240 AutoMutex _l(mLock);
241
242 handle_entry* e = lookupHandleLocked(handle);
243
244 if (e != NULL) {
245 // We need to create a new BpBinder if there isn't currently one, OR we
246 // are unable to acquire a weak reference on this current one. The
247 // attemptIncWeak() is safe because we know the BpBinder destructor will always
248 // call expungeHandle(), which acquires the same lock we are holding now.
249 // We need to do this because there is a race condition between someone
250 // releasing a reference on this BpBinder, and a new reference on its handle
251 // arriving from the driver.
252 IBinder* b = e->binder;
253 if (b == NULL || !e->refs->attemptIncWeak(this)) {
254 b = new BpBinder(handle);
255 result = b;
256 e->binder = b;
257 if (b) e->refs = b->getWeakRefs();
258 } else {
259 result = b;
260 e->refs->decWeak(this);
261 }
262 }
263
264 return result;
265}
166ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
167{
168 const size_t N=mHandleToObject.size();
169 if (N <= (size_t)handle) {
170 handle_entry e;
171 e.binder = NULL;
172 e.refs = NULL;
173 status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
174 if (err < NO_ERROR) return NULL;
175 }
176 return &mHandleToObject.editItemAt(handle);
177}
77 struct handle_entry {
78 IBinder* binder;
79 RefBase::weakref_type* refs;
80 };
上面的代码是在讲,ProcessState里有一个缓存mHandleToObject,缓存的元素是 handle_entry,创建出来的BpBinder对象,挂在handle_entry的binder指针上,BpBinder有继承到RefBase的一些血统,所以BpBinder对象的弱引用挂在handle_entry的refs指针上。
创建,并返回Bpbinder后,继续javaObjectForIBinder:
547jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
548{
549 if (val == NULL) return NULL;
550
551 if (val->checkSubclass(&gBinderOffsets)) {
552 // One of our own!
553 jobject object = static_cast<JavaBBinder*>(val.get())->object();
554 LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
555 return object;
556 }
557
558 // For the rest of the function we will hold this lock, to serialize
559 // looking/creation of Java proxies for native Binder proxies.
560 AutoMutex _l(mProxyLock);
561
562 // Someone else's... do we know about it?
563 jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
564 if (object != NULL) {
565 jobject res = jniGetReferent(env, object);
566 if (res != NULL) {
567 ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
568 return res;
569 }
570 LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
571 android_atomic_dec(&gNumProxyRefs);
572 val->detachObject(&gBinderProxyOffsets);
573 env->DeleteGlobalRef(object);
574 }
575
576 object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
577 if (object != NULL) {
578 LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
579 // The proxy holds a reference to the native object.
580 env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
581 val->incStrong((void*)javaObjectForIBinder);
582
583 // The native object needs to hold a weak reference back to the
584 // proxy, so we can retrieve the same proxy if it is still active.
585 jobject refObject = env->NewGlobalRef(
586 env->GetObjectField(object, gBinderProxyOffsets.mSelf));
587 val->attachObject(&gBinderProxyOffsets, refObject,
588 jnienv_to_javavm(env), proxy_cleanup);
589
590 // Also remember the death recipients registered on this proxy
591 sp<DeathRecipientList> drl = new DeathRecipientList;
592 drl->incStrong((void*)javaObjectForIBinder);
593 env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
594
595 // Note that a new object reference has been created.
596 android_atomic_inc(&gNumProxyRefs);
597 incRefsCreated(env);
598 }
599
600 return object;
601}
看jobject object = (jobject)val->findObject(&gBinderProxyOffsets);这一句,sp是google工程师编写的指针处理类强引用,相应的还有弱引用wp,引用基类RefBase,他们都是在管理在堆中创建过的对象,何时释放。sp重载了操作符->,所以findObject调至BpBinder的findObject。
先来看参数gBinderProxyOffsets是什么东西。
95static struct binderproxy_offsets_t
96{
97 // Class state.
98 jclass mClass;
99 jmethodID mConstructor;
100 jmethodID mSendDeathNotice;
101
102 // Object state.
103 jfieldID mObject;
104 jfieldID mSelf;
105 jfieldID mOrgue;
106
107} gBinderProxyOffsets;
gBinderProxyOffsets结构记录这java层的BinderProxy类的一些字段和方法:
final class BinderProxy implements IBinder {
。。。。。。
540 BinderProxy() {
541 mSelf = new WeakReference(this);
542 }
。。。。。
555 private static final void sendDeathNotice(DeathRecipient recipient) {
556 if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient);
557 try {
558 recipient.binderDied();
559 }
560 catch (RuntimeException exc) {
561 Log.w("BinderNative", "Uncaught exception from death notification",
562 exc);
563 }
564 }
。。。。。。
501 public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
502 Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
503 return transactNative(code, data, reply, flags);
504 }
。。。。。。
507 public native boolean transactNative(int code, Parcel data, Parcel reply,
508 int flags) throws RemoteException;
。。。。。。
566 final private WeakReference mSelf;
567 private long mObject;//BpBinder的指针值,缓存在mHandleToObject中
568 private long mOrgue;
569}
记录的过程在int_register_android_os_BinderProxy(JNIEnv* env)中,也在/frameworks/base/core/jni/android_util_Binder.cpp中。
1254static int int_register_android_os_BinderProxy(JNIEnv* env)
1255{
1256 jclass clazz = FindClassOrDie(env, "java/lang/Error");
1257 gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1258
1259 clazz = FindClassOrDie(env, kBinderProxyPathName);
1260 gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1261 gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
1262 gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
1263 "(Landroid/os/IBinder$DeathRecipient;)V");
1264
1265 gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
1266 gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
1267 "Ljava/lang/ref/WeakReference;");
1268 gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
1269
1270 clazz = FindClassOrDie(env, "java/lang/Class");
1271 gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
1272
1273 return RegisterMethodsOrDie(
1274 env, kBinderProxyPathName,
1275 gBinderProxyMethods, NELEM(gBinderProxyMethods));
1276}
再来接着前面来看看 BpBinder::findObject方法:
class BpBinder : public IBinder
{
public:
......
class ObjectManager
{
......
void* find(const void* objectID) const;
。。。。。。
private:
struct entry_t
{
void* object;//创建的java层对象的一个弱引用
void* cleanupCookie;
IBinder::object_cleanup_func func;
};
KeyedVector<const void*, entry_t> mObjects;//缓存
......
}
。。。。。。
void* BpBinder::findObject(const void* objectID) const;
。。。。。。
private:
ObjectManager mObjects;
}
294void* BpBinder::findObject(const void* objectID) const
295{
296 AutoMutex _l(mLock);
297 return mObjects.find(objectID);
298}
61void* BpBinder::ObjectManager::find(const void* objectID) const
62{
63 const ssize_t i = mObjects.indexOfKey(objectID);
64 if (i < 0) return NULL;
65 return mObjects.valueAt(i).object;
66}
BpBinder的findObject方法其实是在缓存ObjectManager里,根据记录java类BinderProxy的gBinderProxyOffsets变量查找java类的BinderProxy对象,找到就返回,找不到再创建一个,并存储在BpBinder这个对象的缓存里,创建的代码还在javaObjectForIBinder方法里。
Bpbinder对象里有对应的java层对象的缓存,其实可以缓存(对应)各种类型的java层对象,这里主要只有一个类型是BinderProxy。
这里缓存的key是就是该结构体变量gBinderProxyOffsets的地址值,value就是一个entry_t结构体对象,其中object指针指向新创建的BinderProxy对象的mSelf字段值,它是本对象的弱引用。Bpbinder析构的时候,会清理掉这些缓存。
上面提到了BinderProxy对象的创建,假如, jobject object = (jobject)val->findObject(&gBinderProxyOffsets);没找到缓存,那就有:
576 object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
创建一个。
创建完成之后,把对应的BpBinder对象的地址赋给新创建的BinderProxy对象的mObject字段,这样BinderProxy对象持有了BpBinder对象的地址,BpBinder对象缓存了BinderProxy对象,都可以在各自的层级通过jni“索引”到对方;接着把BinderProxy对象的mSelf弱引用拿出去(它在构造方法里已经初始化完了),来构建Bpbinder缓存里的entry_t元素,所以entry_t元素的object指针指向Bindproxy的弱引用,而不是指向Bindproxy对象,Bindproxy对象就可以被GC回收。
576 object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
577 if (object != NULL) {
578 LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
579 // The proxy holds a reference to the native object.
580 env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
581 val->incStrong((void*)javaObjectForIBinder);
582
583 // The native object needs to hold a weak reference back to the
584 // proxy, so we can retrieve the same proxy if it is still active.
585 jobject refObject = env->NewGlobalRef(
586 env->GetObjectField(object, gBinderProxyOffsets.mSelf));
587 val->attachObject(&gBinderProxyOffsets, refObject,
588 jnienv_to_javavm(env), proxy_cleanup);//拿出弱引用去构建缓存元素
589
。。。。。。
598 }
接着从javaObjectForIBinder返回一个Bindproxy对象到BinderInternal.java的getContextObject(),getContextObject()再返回到ServiceManager的getIServiceManager方法里,具体返回的地方:
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
再看ServiceManagerNative.asInterface方法:
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);
}
而obj.queryLocalInterface == null:
493final class BinderProxy implements IBinder {
。。。。。。
497 public IInterface queryLocalInterface(String descriptor) {
498 return null;
499 }
。。。。。。
}
所以,getIServiceManager()返回了new ServiceManagerProxy(new BinderProxy());接着看ServiceManager的getService(servicename)方法:
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
接着看ServiceManagerProxy的getService:
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
public IBinder asBinder() {
return 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 binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
。。。。。。
mRemote就是c++创建的jvm管控的BinderProxy对象,我们关注mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);这一句,.transact为BinderProxy的native方法,对应/frameworks/base/core/jni/android_util_Binder.cpp中的(void*)android_os_BinderProxy_transact方法:
1083static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
1084 jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
1085{
86 if (dataObj == NULL) {
1087 jniThrowNullPointerException(env, NULL);
1088 return JNI_FALSE;
1089 }
1090
1091 Parcel* data = parcelForJavaObject(env, dataObj);
1092 if (data == NULL) {
1093 return JNI_FALSE;
1094 }
1095 Parcel* reply = parcelForJavaObject(env, replyObj);
1096 if (reply == NULL && replyObj != NULL) {
1097 return JNI_FALSE;
1098 }
1099
1100 IBinder* target = (IBinder*)
1101 env->GetLongField(obj, gBinderProxyOffsets.mObject);
status_t err = target->transact(code, *data, reply, flags);
......
}
上面的target就是上次创建BinderProxy对象后赋给其mObject字段的c++层的BpBinder的地址值,所以target->transact(code, *data, reply, flags);这一句就是BpBinder->transact(code, *data, reply, flags);
BpBinder就是c++层的通信基础类,丢给它的参数,都会通过binder驱动的mmap操作,一次copy给目标进程,这里的目标进程就是Servicemanager进程。
至于AlarmManager那种方式,有一步是IAlarmManager service = IAlarmManager.Stub.asInterface(b);如果你自己创建aidl文件的话,这一步就是把ServiceManager.getService(Context.ALARM_SERVICE);返回的BinderProxy对象传给IAlarmManager.Stub.Proxy对象持有,IAlarmManager.Stub.Proxy对象实现了IAlarmManager接口,它作为业务通信类,持有基础通信类BinderProxy对象来向binder驱动传输命令。
总结一下,上面说到的调用各大服务的接口的过程:
1.要先获取到servicemanage服务进程的代理对象,new ServiceManagerProxy(new BinderPRoxy());
2.再getService(servicename),其实是调用BinderPRoxy的transact native方法,而BinderPRoxy通过持有c++层的BpBinder的指针值的mObject字段,找到对应的c++层的BpBinder对象,然后调用BpBinder的transact方法,把参数发送给binder驱动。
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;
}
3.驱动把返回的bind引用,放到c++层的reply中,不是上面的reply,c++层中reply通过readStrongBinder()先读到一个Bpbinder对象,然后把BpBinder通过上面所说的javaObjectForIBinder方法,就返回了java层的BinderProxy对象。
// c+层的reply接收返回的binder引用资源
reply->ipcSetDataReference(
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),//内核给的binder引用在里面
tr.data_size,
reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(size_t),
freeBuffer, this);
// java侧的readStrongBinder(),调至native的jobject android_os_Parcel_readStrongBinder
public final IBinder readStrongBinder() {
return nativeReadStrongBinder(mNativePtr);
}
//{"nativeReadStrongBinder", "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder}
425static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
426{
427 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
428 if (parcel != NULL) {
429 return javaObjectForIBinder(env, parcel->readStrongBinder());//返回BinderProxy对象
430 }
431 return NULL;
432}
其实java层的Parcel 和c++层的Parcel 通过java层持有c++层的Parcel对象的指针一一对应起来,而它们的读和写的缓存都在c++层,从而保持了其中数据的一致性。
547static jlong android_os_Parcel_create(JNIEnv* env, jclass clazz)
548{
549 Parcel* parcel = new Parcel();
550 return reinterpret_cast<jlong>(parcel);
551}
再总结:
返回给客户端的 代理service都长这样:new XXXServiceProxy(new BinderPRoxy());
BinderPRoxy.java对象在c++层创建,并缓存在BpBinder.cpp对象的缓存里;而BpBinder.cpp对象的地址值挂在BinderPRoxy.java对象的mObject字段上,从而完成“福利合照”;
类似的,java层的Parcel 和c++层的Parcel 通过java层持有c++层的Parcel对象的指针一一对应起来,并且他们的读写都反应在c++层的Parcel对象的缓存里。
转载注明出处。