Android开发之漫漫长途 Ⅷ——Android Binder(也许是最容易理解的) (4)

我们来一一分析,在分析问题之前我们先做一个假设,这个假设至关重要,那就是不管我们的SystemServer进程与SM进程交互也好还是我们的App进程与SM进程也好,SM的代理已经事先创建完毕,即不管我们在SystemServer端还是App端,在与SM进程交互的时候不用考虑代理怎么获得的。为什么会有如此假设,因为我自己深受其害,由于上述三个过程均是通过Binder,很容易陷入思维混乱。

AMS是如何注册的?

我们SystemServer进程中的AMS通过"Socket"与SM进程交互,并把自己注册在SM中
SystemServer创建出ActivityManagerService后,最终将调用其setSystemProcess方法:

[SystemServer.java]

public void setSystemProcess() { try { //注册服务,第二个参数为this,这里通过“socket”与SM交互 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); .......... } catch (PackageManager.NameNotFoundException e) { ........ } }

上面的请求最终是通过SM服务代理发送的()

[ServiceManagerNative.java]

public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException { //将数据打包写入Parcel对象 Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); //注意这个地方,后文分析,此时的service为ActivityManagerService data.writeStrongBinder(service); data.writeInt(allowIsolated ? 1 : 0); //调用BindProxy的transact函数 mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); }

上面的过程已经分析过了, 这里我们主要看一下哪个对应的native层的transact函数

[android_ util_Binder.cpp]

static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) { ........ //将java对象转化为native对象 Parcel* data = parcelForJavaObject(env, dataObj); ......... Parcel* reply = parcelForJavaObject(env, replyObj); ........ //得到native层的BpBinder IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject); ........ //通过BpBinder利用IPCThreadState,将请求通过Binder驱动发送给SM进程 status_t err = target->transact(code, *data, reply, flags); ........ }

SM进程收到信息后便处理这个消息(这个说法并不准确,准确的说法是,SM进程中主线程一直在与binder设备交互,想必读者也猜到了for(;;)),有消息时便通过预先定义好的函数进行处理

[service_manager.c]

switch(txn->code) { case SVC_MGR_ADD_SERVICE: s = bio_get_string16(msg, &len); if (s == NULL) { return -1; } handle = bio_get_ref(msg); allow_isolated = bio_get_uint32(msg) ? 1 : 0; //do_add_service if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, txn->sender_pid)) return -1; break; } int do_add_service(struct binder_state *bs, const uint16_t *s, size_t len, uint32_t handle, uid_t uid, int allow_isolated, pid_t spid) { //结构体si,用来存储服务信息 struct svcinfo *si; //判断服务有没有权限注册,并不是所有的服务都能注册 if (!svc_can_register(s, len, spid)) { return -1; } //查询服务有没有注册过 si = find_svc(s, len); if (si) {//已经注册过 if (si->handle) { ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n", str8(s, len), handle, uid); svcinfo_death(bs, si); } si->handle = handle; } else {//还没有注册过,我们进入这个分支 si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t)); if (!si) { ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n", str8(s, len), handle, uid); return -1; } //保存一些handle等信息 si->handle = handle; si->len = len; memcpy(si->name, s, (len + 1) * sizeof(uint16_t)); si->name[len] = '\0'; si->death.func = (void*) svcinfo_death; si->death.ptr = si; si->allow_isolated = allow_isolated; si->next = svclist; svclist = si; } binder_acquire(bs, handle); binder_link_to_death(bs, handle, &si->death); return 0; }

看到这里SM貌似只保留了一些AMS的信息而已,实际上并不只是如此,我们来看一下上面的保留问题

[Parcel.java]

data.writeStrongBinder(service); public final void writeStrongBinder(IBinder val) { //调用了native函数 nativeWriteStrongBinder(mNativePtr, val); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjpzf.html