跟上篇Binder使用一样,先通过例子来跟踪JavaBinder机制。本文参考了Binder In java

http://www.cnblogs.com/angeldevil/p/3328748.html,只作为研究android记忆用

Init进程的init2阶段,系统启动了ServerThread,在ServerThread中会启动很多用Java实现的系统服务

frameworks/base/services/java/com/android/server/SystemServer.java

代码

power = new PowerManagerService();ServiceManager.addService(Context.POWER_SERVICE, power);context = ActivityManagerService.main(factoryTest);Slog.i(TAG, "Display Manager");display = new DisplayManagerService(context, wmHandler, uiHandler);ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);

通过ServiceManageraddService注册为binder server端。

 

我们以PowerManagerService为例,

frameworks/base/services/java/com/android/server/power/


PowerManagerService继承于IPowerManager.stub,IPowerManager.stub位于

frameworks/base/core/java/com/android/os/IPowerManager.aidl


package android.os;import android.os.WorkSource;/** @hide */interface IPowerManager{    // WARNING: The first two methods must remain the first two methods because their    // transaction numbers must not change unless IPowerManager.cpp is also updated.    void acquireWakeLock(IBinder lock, int flags, String tag, in WorkSource ws);    void releaseWakeLock(IBinder lock, int flags);    void updateWakeLockWorkSource(IBinder lock, in WorkSource ws);    boolean isWakeLockLevelSupported(int level);    void userActivity(long time, int event, int flags);    void wakeUp(long time);    void goToSleep(long time, int reason);    void nap(long time);    boolean isScreenOn();    void reboot(boolean confirm, String reason, boolean wait);    void shutdown(boolean confirm, boolean wait);    void crash(String message);    void setStayOnSetting(int val);    void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs);    // temporarily overrides the screen brightness settings to allow the user to    // see the effect of a settings change without applying it immediately    void setTemporaryScreenBrightnessSettingOverride(int brightness);    void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj);    // sets the attention light (used by phone app only)    void setAttentionLight(boolean on, int color);}

Aidlandroid内部进程通信接口的描述语言,通过编译我们可以编译出



package android.os;/** @hide */public interface IPowerManager extends android.os.IInterface {/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implementsandroid.os.IPowerManager {private static final java.lang.String DESCRIPTOR = "android.os.IPowerManager";/** Construct the stub at attach it to the interface. */public Stub() {this.attachInterface(this, DESCRIPTOR);}/** * Cast an IBinder object into an android.os.IPowerManager interface, * generating a proxy if needed. */public static android.os.IPowerManager asInterface(android.os.IBinder obj) {if ((obj == null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin != null) && (iin instanceof android.os.IPowerManager))) {return ((android.os.IPowerManager) iin);}return new android.os.IPowerManager.Stub.Proxy(obj);}@Overridepublic android.os.IBinder asBinder() {return this;}@Overridepublic boolean onTransact(int code, android.os.Parcel data,android.os.Parcel reply, int flags)throws android.os.RemoteException {switch (code) {case INTERFACE_TRANSACTION: {reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_acquireWakeLock: {data.enforceInterface(DESCRIPTOR);android.os.IBinder _arg0;_arg0 = data.readStrongBinder();int _arg1;_arg1 = data.readInt();java.lang.String _arg2;_arg2 = data.readString();android.os.WorkSource _arg3;if ((0 != data.readInt())) {_arg3 = android.os.WorkSource.CREATOR.createFromParcel(data);} else {_arg3 = null;}this.acquireWakeLock(_arg0, _arg1, _arg2, _arg3);reply.writeNoException();return true;}case TRANSACTION_releaseWakeLock: {data.enforceInterface(DESCRIPTOR);android.os.IBinder _arg0;_arg0 = data.readStrongBinder();int _arg1;_arg1 = data.readInt();this.releaseWakeLock(_arg0, _arg1);reply.writeNoException();return true;}case TRANSACTION_updateWakeLockWorkSource: {data.enforceInterface(DESCRIPTOR);android.os.IBinder _arg0;_arg0 = data.readStrongBinder();android.os.WorkSource _arg1;if ((0 != data.readInt())) {_arg1 = android.os.WorkSource.CREATOR.createFromParcel(data);} else {_arg1 = null;}this.updateWakeLockWorkSource(_arg0, _arg1);reply.writeNoException();return true;}case TRANSACTION_isWakeLockLevelSupported: {data.enforceInterface(DESCRIPTOR);int _arg0;_arg0 = data.readInt();boolean _result = this.isWakeLockLevelSupported(_arg0);reply.writeNoException();reply.writeInt(((_result) ? (1) : (0)));return true;}case TRANSACTION_userActivity: {data.enforceInterface(DESCRIPTOR);long _arg0;_arg0 = data.readLong();int _arg1;_arg1 = data.readInt();int _arg2;_arg2 = data.readInt();this.userActivity(_arg0, _arg1, _arg2);reply.writeNoException();return true;}case TRANSACTION_wakeUp: {data.enforceInterface(DESCRIPTOR);long _arg0;_arg0 = data.readLong();this.wakeUp(_arg0);reply.writeNoException();return true;}case TRANSACTION_goToSleep: {data.enforceInterface(DESCRIPTOR);long _arg0;_arg0 = data.readLong();int _arg1;_arg1 = data.readInt();this.goToSleep(_arg0, _arg1);reply.writeNoException();return true;}case TRANSACTION_nap: {data.enforceInterface(DESCRIPTOR);long _arg0;_arg0 = data.readLong();this.nap(_arg0);reply.writeNoException();return true;}case TRANSACTION_isScreenOn: {data.enforceInterface(DESCRIPTOR);boolean _result = this.isScreenOn();reply.writeNoException();reply.writeInt(((_result) ? (1) : (0)));return true;}case TRANSACTION_reboot: {data.enforceInterface(DESCRIPTOR);boolean _arg0;_arg0 = (0 != data.readInt());java.lang.String _arg1;_arg1 = data.readString();boolean _arg2;_arg2 = (0 != data.readInt());this.reboot(_arg0, _arg1, _arg2);reply.writeNoException();return true;}case TRANSACTION_shutdown: {data.enforceInterface(DESCRIPTOR);boolean _arg0;_arg0 = (0 != data.readInt());boolean _arg1;_arg1 = (0 != data.readInt());this.shutdown(_arg0, _arg1);reply.writeNoException();return true;}case TRANSACTION_crash: {data.enforceInterface(DESCRIPTOR);java.lang.String _arg0;_arg0 = data.readString();this.crash(_arg0);reply.writeNoException();return true;}case TRANSACTION_setStayOnSetting: {data.enforceInterface(DESCRIPTOR);int _arg0;_arg0 = data.readInt();this.setStayOnSetting(_arg0);reply.writeNoException();return true;}case TRANSACTION_setMaximumScreenOffTimeoutFromDeviceAdmin: {data.enforceInterface(DESCRIPTOR);int _arg0;_arg0 = data.readInt();this.setMaximumScreenOffTimeoutFromDeviceAdmin(_arg0);reply.writeNoException();return true;}case TRANSACTION_setTemporaryScreenBrightnessSettingOverride: {data.enforceInterface(DESCRIPTOR);int _arg0;_arg0 = data.readInt();this.setTemporaryScreenBrightnessSettingOverride(_arg0);reply.writeNoException();return true;}case TRANSACTION_setTemporaryScreenAutoBrightnessAdjustmentSettingOverride: {data.enforceInterface(DESCRIPTOR);float _arg0;_arg0 = data.readFloat();this.setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(_arg0);reply.writeNoException();return true;}case TRANSACTION_setAttentionLight: {data.enforceInterface(DESCRIPTOR);boolean _arg0;_arg0 = (0 != data.readInt());int _arg1;_arg1 = data.readInt();this.setAttentionLight(_arg0, _arg1);reply.writeNoException();return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements android.os.IPowerManager {private android.os.IBinder mRemote;Proxy(android.os.IBinder remote) {mRemote = remote;}@Overridepublic android.os.IBinder asBinder() {return mRemote;}public java.lang.String getInterfaceDescriptor() {return DESCRIPTOR;}// WARNING: The first two methods must remain the first two methods// because their// transaction numbers must not change unless IPowerManager.cpp is// also updated.@Overridepublic void acquireWakeLock(android.os.IBinder lock, int flags,java.lang.String tag, android.os.WorkSource ws)throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeStrongBinder(lock);_data.writeInt(flags);_data.writeString(tag);if ((ws != null)) {_data.writeInt(1);ws.writeToParcel(_data, 0);} else {_data.writeInt(0);}mRemote.transact(Stub.TRANSACTION_acquireWakeLock, _data,_reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}@Overridepublic void releaseWakeLock(android.os.IBinder lock, int flags)throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeStrongBinder(lock);_data.writeInt(flags);mRemote.transact(Stub.TRANSACTION_releaseWakeLock, _data,_reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}@Overridepublic void updateWakeLockWorkSource(android.os.IBinder lock,android.os.WorkSource ws) throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeStrongBinder(lock);if ((ws != null)) {_data.writeInt(1);ws.writeToParcel(_data, 0);} else {_data.writeInt(0);}mRemote.transact(Stub.TRANSACTION_updateWakeLockWorkSource,_data, _reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}@Overridepublic boolean isWakeLockLevelSupported(int level)throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();boolean _result;try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(level);mRemote.transact(Stub.TRANSACTION_isWakeLockLevelSupported,_data, _reply, 0);_reply.readException();_result = (0 != _reply.readInt());} finally {_reply.recycle();_data.recycle();}return _result;}@Overridepublic void userActivity(long time, int event, int flags)throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeLong(time);_data.writeInt(event);_data.writeInt(flags);mRemote.transact(Stub.TRANSACTION_userActivity, _data,_reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}@Overridepublic void wakeUp(long time) throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeLong(time);mRemote.transact(Stub.TRANSACTION_wakeUp, _data, _reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}@Overridepublic void goToSleep(long time, int reason)throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeLong(time);_data.writeInt(reason);mRemote.transact(Stub.TRANSACTION_goToSleep, _data, _reply,0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}@Overridepublic void nap(long time) throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeLong(time);mRemote.transact(Stub.TRANSACTION_nap, _data, _reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}@Overridepublic boolean isScreenOn() throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();boolean _result;try {_data.writeInterfaceToken(DESCRIPTOR);mRemote.transact(Stub.TRANSACTION_isScreenOn, _data,_reply, 0);_reply.readException();_result = (0 != _reply.readInt());} finally {_reply.recycle();_data.recycle();}return _result;}@Overridepublic void reboot(boolean confirm, java.lang.String reason,boolean wait) throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(((confirm) ? (1) : (0)));_data.writeString(reason);_data.writeInt(((wait) ? (1) : (0)));mRemote.transact(Stub.TRANSACTION_reboot, _data, _reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}@Overridepublic void shutdown(boolean confirm, boolean wait)throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(((confirm) ? (1) : (0)));_data.writeInt(((wait) ? (1) : (0)));mRemote.transact(Stub.TRANSACTION_shutdown, _data, _reply,0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}@Overridepublic void crash(java.lang.String message)throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeString(message);mRemote.transact(Stub.TRANSACTION_crash, _data, _reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}@Overridepublic void setStayOnSetting(int val)throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(val);mRemote.transact(Stub.TRANSACTION_setStayOnSetting, _data,_reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}@Overridepublic void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs)throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(timeMs);mRemote.transact(Stub.TRANSACTION_setMaximumScreenOffTimeoutFromDeviceAdmin,_data, _reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}// temporarily overrides the screen brightness settings to allow the// user to// see the effect of a settings change without applying it// immediately@Overridepublic void setTemporaryScreenBrightnessSettingOverride(int brightness) throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(brightness);mRemote.transact(Stub.TRANSACTION_setTemporaryScreenBrightnessSettingOverride,_data, _reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}@Overridepublic void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj) throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeFloat(adj);mRemote.transact(Stub.TRANSACTION_setTemporaryScreenAutoBrightnessAdjustmentSettingOverride,_data, _reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}// sets the attention light (used by phone app only)@Overridepublic void setAttentionLight(boolean on, int color)throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(((on) ? (1) : (0)));_data.writeInt(color);mRemote.transact(Stub.TRANSACTION_setAttentionLight, _data,_reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}}static final int TRANSACTION_acquireWakeLock = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);static final int TRANSACTION_releaseWakeLock = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);static final int TRANSACTION_updateWakeLockWorkSource = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);static final int TRANSACTION_isWakeLockLevelSupported = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);static final int TRANSACTION_userActivity = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);static final int TRANSACTION_wakeUp = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);static final int TRANSACTION_goToSleep = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6);static final int TRANSACTION_nap = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7);static final int TRANSACTION_isScreenOn = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8);static final int TRANSACTION_reboot = (android.os.IBinder.FIRST_CALL_TRANSACTION + 9);static final int TRANSACTION_shutdown = (android.os.IBinder.FIRST_CALL_TRANSACTION + 10);static final int TRANSACTION_crash = (android.os.IBinder.FIRST_CALL_TRANSACTION + 11);static final int TRANSACTION_setStayOnSetting = (android.os.IBinder.FIRST_CALL_TRANSACTION + 12);static final int TRANSACTION_setMaximumScreenOffTimeoutFromDeviceAdmin = (android.os.IBinder.FIRST_CALL_TRANSACTION + 13);static final int TRANSACTION_setTemporaryScreenBrightnessSettingOverride = (android.os.IBinder.FIRST_CALL_TRANSACTION + 14);static final int TRANSACTION_setTemporaryScreenAutoBrightnessAdjustmentSettingOverride = (android.os.IBinder.FIRST_CALL_TRANSACTION + 15);static final int TRANSACTION_setAttentionLight = (android.os.IBinder.FIRST_CALL_TRANSACTION + 16);}// WARNING: The first two methods must remain the first two methods because// their// transaction numbers must not change unless IPowerManager.cpp is also// updated.public void acquireWakeLock(android.os.IBinder lock, int flags,java.lang.String tag, android.os.WorkSource ws)throws android.os.RemoteException;public void releaseWakeLock(android.os.IBinder lock, int flags)throws android.os.RemoteException;public void updateWakeLockWorkSource(android.os.IBinder lock,android.os.WorkSource ws) throws android.os.RemoteException;public boolean isWakeLockLevelSupported(int level)throws android.os.RemoteException;public void userActivity(long time, int event, int flags)throws android.os.RemoteException;public void wakeUp(long time) throws android.os.RemoteException;public void goToSleep(long time, int reason)throws android.os.RemoteException;public void nap(long time) throws android.os.RemoteException;public boolean isScreenOn() throws android.os.RemoteException;public void reboot(boolean confirm, java.lang.String reason, boolean wait)throws android.os.RemoteException;public void shutdown(boolean confirm, boolean wait)throws android.os.RemoteException;public void crash(java.lang.String message)throws android.os.RemoteException;public void setStayOnSetting(int val) throws android.os.RemoteException;public void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs)throws android.os.RemoteException;// temporarily overrides the screen brightness settings to allow the user to// see the effect of a settings change without applying it immediatelypublic void setTemporaryScreenBrightnessSettingOverride(int brightness)throws android.os.RemoteException;public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj) throws android.os.RemoteException;// sets the attention light (used by phone app only)public void setAttentionLight(boolean on, int color)throws android.os.RemoteException;}

我们可以从代码中看到Stub是一个抽象类,里面还有个proxy

Stub提供asInterface asBinder onTransact 


                    PowerManagerService




其实这个是不是看起来很熟悉呢,我们回忆下MediaplayerServiceMediaplayerService 继承于BnMediaPlayerService,BnMediaPlayerService刚好跟这个Stub很类似,

然后我们再看看proxy类是不是跟BpMediaPlayerService类似,而IPowerManager则跟IMediaPlayerService类似,而PowerManagerServic则跟MediaplayerService一样实现功能。

Stub继承于Binder,而在Binder构造函数中调用nativeinit

framework\base\core\jni\android_util_Binder.cpp

static void android_os_Binder_init(JNIEnv* env, jobject obj){    JavaBBinderHolder* jbh = new JavaBBinderHolder();    if (jbh == NULL) {        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);        return;    }    ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);    jbh->incStrong((void*)android_os_Binder_init);    env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh);}

可以看出创建了一个JavaBBinderHolder,然后把值强制转int,返回给javaBinder类的

private int mObject;

AndroidRuntine::startReg中会调用register_android_os_Binderregister_android_os_Binder会调用int_register_android_os_Binder等函数建立JavaBinderBinderProxyBinderInternalLog等与Native层的映射关系

Native层对java层的反射

static int int_register_android_os_Binder(JNIEnv* env){    jclass clazz;    clazz = env->FindClass(kBinderPathName);    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder");    gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz);    gBinderOffsets.mExecTransact        = env->GetMethodID(clazz, "execTransact", "(IIII)Z");    assert(gBinderOffsets.mExecTransact);    gBinderOffsets.mObject        = env->GetFieldID(clazz, "mObject", "I");    assert(gBinderOffsets.mObject);    return AndroidRuntime::registerNativeMethods(        env, kBinderPathName,        gBinderMethods, NELEM(gBinderMethods));}

JavaBBinderHolder是什么呢?

android_os_Binder_initnew了一个JavaBBinderHolderJavaBBinderHolder get()函数new了一个JavaBBinder保存到了自己的成员sp mBinder中。而JavaBBinder继承自Native层的BBinder,还记得在IPC thread中接收binder的数据,并且通过BBinder回调的,然后再调用BnXXonTransact执行Server端的相关命令

有了这些我们可以猜测IPowerManager.aidl编译出来的文件就是binder机制中Server


 

 

现在既然知道了PowerManagerServicebinderserver端,那他怎么在java层向binder注册呢,还有client端怎么在java层获取Service

 

首先,按着binder的机制,ServiceManager.addService(Context.POWER_SERVICE, power);

我们查看ServiceManager


(frameworks/base/core/java/android/os/ServiceManager.java)

public static void addService(String name, IBinder service, boolean allowIsolated) {        try {            getIServiceManager().addService(name, service, allowIsolated);        } catch (RemoteException e) {            Log.e(TAG, "error in addService", e);        }    }     private static IServiceManager getIServiceManager() {        if (sServiceManager != null) {            return sServiceManager;        }        // Find the service manager        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());        return sServiceManager;}

从代码可以看出addService是调用了ServiceManagerNative,而asInterface则是传入一个IBinder对象,并创建出ServiceManagerProxy,是不是跟Mediaplayer Server获取binder smgr有点类似?

public void addService(String name, IBinder service, boolean allowIsolated)            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);        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);        reply.recycle();        data.recycle();    }

我们在看看BinderInternal.getContextObject(),他是一个native函数,我们到native层看看是不是跟Mediaplayer Server一样通过new Bpbinder(0),获取到Binder smgr

framework\base\core\jni\android_util_Binder.cpp

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz){    sp b = ProcessState::self()->getContextObject(NULL);    return javaObjectForIBinder(env, b);}
jobject javaObjectForIBinder(JNIEnv* env, const sp& val){    if (val == NULL) return NULL;    if (val->checkSubclass(&gBinderOffsets)) {// BpBinder没重写,返回false        // One of our own!        jobject object = static_cast(val.get())->object();        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);        return object;    }    // For the rest of the function we will hold this lock, to serialize    // looking/creation of Java proxies for native Binder proxies.    AutoMutex _l(mProxyLock);    // Someone else's...  do we know about it?// BpBinder没有带proxy过来    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);    if (object != NULL) {        jobject res = jniGetReferent(env, object);        if (res != NULL) {            ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);            return res;        }        LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());        android_atomic_dec(&gNumProxyRefs);        val->detachObject(&gBinderProxyOffsets);        env->DeleteGlobalRef(object);    }    // 因为proxy,创建一个proxy   // const char* const kBinderProxyPathName = "android/os/BinderProxy";    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);    if (object != NULL) {        LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);        // The proxy holds a reference to the native object.        env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get()); // 把BpBinder(0)赋值给BinderProxy 的mObject        val->incStrong((void*)javaObjectForIBinder);        // The native object needs to hold a weak reference back to the        // proxy, so we can retrieve the same proxy if it is still active.        jobject refObject = env->NewGlobalRef(                env->GetObjectField(object, gBinderProxyOffsets.mSelf));        val->attachObject(&gBinderProxyOffsets, refObject,                jnienv_to_javavm(env), proxy_cleanup);        // Also remember the death recipients registered on this proxy        sp drl = new DeathRecipientList;        drl->incStrong((void*)javaObjectForIBinder);        env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast(drl.get()));        // Note that a new object reference has been created.        android_atomic_inc(&gNumProxyRefs);        incRefsCreated(env);    }    return object;}

可以看出返回了android.os.BinderProxy

也就是说ServiceManagerProxymRemote带的BinderProxy

frameworks/base/core/java/com/android/os/Binder.java)

而里面的Transact是调用native层的android_os_BinderProxy_transact

frameworks/base/core/jni/android/android.util.Binder.cpp)



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->GetIntField(obj, gBinderProxyOffsets.mObject); //此时的mObject为BpBinder(0);     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 %d\n",            target, obj, code);    // Only log the binder call duration for things on the Java-level main thread.    // But if we don't    const bool time_binder_calls = should_time_binder_calls();    int64_t start_millis;    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 (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*/);    return JNI_FALSE;}

看出status_t err = target->transact(code, *data, reply, flags);

是调用了BinderProxy里面mObjectBpbinder(0))的transact来传输数据

 




可以看到跟Mediaplayer Server一样 获取了smgr binder,并通过他通讯给smgr binder

那我们可以归结出ServiceManagerProxy BpServicemanager,并带入了smgr binder,跟binder通讯

 

 

 

其次,我们在java层获取Service是通过

Context.getSystemService(Context.POWER_SERVICE);

getSystemService位于ContextImpl

(frameworks/base/core/java/com/android/app/ContextImpl.java)


@Override    public Object getSystemService(String name) {        ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);        return fetcher == null ? null : fetcher.getService(this);}


Static{.... registerService(POWER_SERVICE, new ServiceFetcher() {                public Object createService(ContextImpl ctx) {                    IBinder b = ServiceManager.getService(POWER_SERVICE);                    IPowerManager service = IPowerManager.Stub.asInterface(b);                    return new PowerManager(ctx.getOuterContext(),                            service, ctx.mMainThread.getHandler());                }});....};

static class ServiceFetcher {        int mContextCacheIndex = -1;        /**         * Main entrypoint; only override if you don't need caching.         */        public Object getService(ContextImpl ctx) {            ArrayList cache = ctx.mServiceCache;            Object service;            synchronized (cache) {                if (cache.size() == 0) {                    // Initialize the cache vector on first access.                    // At this point sNextPerContextServiceCacheIndex                    // is the number of potential services that are                    // cached per-Context.                    for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {                        cache.add(null);                    }                } else {                    service = cache.get(mContextCacheIndex);                    if (service != null) {                        return service;                    }                }                service = createService(ctx);                cache.set(mContextCacheIndex, service);                return service;            }        }        /**         * Override this to create a new per-Context instance of the         * service.  getService() will handle locking and caching.         */        public Object createService(ContextImpl ctx) {            throw new RuntimeException("Not implemented");        }    }   

从代码里面看出,要是从cache中获取不到service,那么


Static{.... registerService(POWER_SERVICE, new ServiceFetcher() {                public Object createService(ContextImpl ctx) {                    IBinder b = ServiceManager.getService(POWER_SERVICE);                    IPowerManager service = IPowerManager.Stub.asInterface(b);                    return new PowerManager(ctx.getOuterContext(),                            service, ctx.mMainThread.getHandler());                }});....};


通过ServiceManager获取到PowerService,并通过Stub转化成IPowerManager,并创建了PowerManager返回给客户端调用。

getService函数就跟addService一样,先获取smgr,然后用ServiceManagerProxy getService获取到binder,然后通过stubasInterface转化为IPowerManager(实际是让其带ServiceBinder

public static android.os.IPowerManager asInterface(android.os.IBinder obj) {if ((obj == null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin != null) && (iin instanceof android.os.IPowerManager))) {return ((android.os.IPowerManager) iin);}return new android.os.IPowerManager.Stub.Proxy(obj);}


Proxy(android.os.IBinder remote) {mRemote = remote;}


更多相关文章

  1. 【转】高通平台android 环境配置编译及开发经验总结
  2. Android工程直接调用monkey源码进行压力测试
  3. Android(安卓)GPS应用:动态获取位置信息
  4. Android(安卓)Service BroadcastReceiver
  5. 一个常见Android崩溃问题的分析
  6. 全面了解Activity
  7. 4.0.x Launcher启动过程
  8. Android开发工具——ADB(Android(安卓)Debug Bridge) HOST端
  9. Android(安卓)Intent原理分析

随机推荐

  1. 服务器端向Android客户端的推送解决方案
  2. Android新手入门2016(15)--Gallery画廊
  3. 源码的完全解析:Android的消息机制
  4. Android版俄罗斯方块的实现
  5. 关于 Android(安卓)7.0 适配中 FileProvi
  6. 只需一篇文章“吃透”Android多线程技术?
  7. 【我的Android进阶之旅】Android(安卓)St
  8. 学习Android一点心得
  9. 图文浅析之Android显示原理
  10. 自适应各种宽度的虚线怎么做?