Java层Binder使用(ServiceManager)
转自:http://blog.csdn.net/jacklam200/article/details/37567409
跟上篇Binder使用一样,先通过例子来跟踪Java层Binder机制。本文参考了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);
通过ServiceManager的addService注册为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);
- }
Aidl是android内部进程通信接口的描述语言,通过编译我们可以编译出
- 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 implements
- android.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);
- }
- @Override
- public android.os.IBinder asBinder() {
- return this;
- }
- @Override
- public 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;
- }
- @Override
- public 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.
- @Override
- public 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();
- }
- }
- @Override
- public 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();
- }
- }
- @Override
- public 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();
- }
- }
- @Override
- public 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;
- }
- @Override
- public 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();
- }
- }
- @Override
- public 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();
- }
- }
- @Override
- public 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();
- }
- }
- @Override
- public 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();
- }
- }
- @Override
- public 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;
- }
- @Override
- public 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();
- }
- }
- @Override
- public 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();
- }
- }
- @Override
- public 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();
- }
- }
- @Override
- public 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();
- }
- }
- @Override
- public 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
- @Override
- public 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();
- }
- }
- @Override
- public 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)
- @Override
- public 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 immediately
- public 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
其实这个是不是看起来很熟悉呢,我们回忆下MediaplayerService,MediaplayerService 继承于BnMediaPlayerService,而BnMediaPlayerService刚好跟这个Stub很类似,
然后我们再看看proxy类是不是跟BpMediaPlayerService类似,而IPowerManager则跟IMediaPlayerService类似,而PowerManagerServic则跟MediaplayerService一样实现功能。
并Stub继承于Binder,而在Binder构造函数中调用native的init
(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,返回给java层Binder类的
- private int mObject;
- </pre><p class="p0" style="margin-bottom:0pt; margin-top:0pt"><span style="font-size:10pt; font-family:宋体">在<span style="font-family:Consolas">AndroidRuntine::startReg</span><span style="font-family:宋体">中会调用</span><span style="font-family:Consolas">register_android_os_Binder</span><span style="font-family:宋体">,</span><span style="font-family:Consolas">register_android_os_Binder</span><span style="font-family:宋体">会调用</span><span style="font-family:Consolas">int_register_android_os_Binder</span><span style="font-family:宋体">等函数建立</span><span style="font-family:Consolas">Java</span><span style="font-family:宋体">层</span><span style="font-family:Consolas">Binder</span><span style="font-family:宋体">、</span><span style="font-family:Consolas">BinderProxy</span><span style="font-family:宋体">、</span><span style="font-family:Consolas">BinderInternal</span><span style="font-family:宋体">、</span><span style="font-family:Consolas">Log</span><span style="font-family:宋体">等与</span><span style="font-family:Consolas">Native</span><span style="font-family:宋体">层的映射关系</span></span><span style="font-size:10pt; font-family:宋体"></span></p><p class="p0" style="margin-bottom:0pt; margin-top:0pt"><span style="font-size:10pt; font-family:宋体">Native<span style="font-family:宋体">层对</span><span style="font-family:Consolas">java</span><span style="font-family:宋体">层的反射</span></span><span style="font-size:10pt; font-family:宋体"></span></p><pre code_snippet_id="422453" snippet_file_name="blog_20140708_7_4207713" name="code" class="cpp">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_init中new了一个JavaBBinderHolder,JavaBBinderHolder 的get()函数new了一个JavaBBinder保存到了自己的成员sp<JavaBBinder> mBinder中。而JavaBBinder继承自Native层的BBinder,还记得在IPC thread中接收binder的数据,并且通过BBinder回调的,然后再调用BnXX的onTransact执行Server端的相关命令
有了这些我们可以猜测IPowerManager.aidl编译出来的文件就是binder机制中Server端
现在既然知道了PowerManagerService是binder的server端,那他怎么在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<IBinder> b = ProcessState::self()->getContextObject(NULL);
- return javaObjectForIBinder(env, b);
- }
- jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
- {
- if (val == NULL) return NULL;
- if (val->checkSubclass(&gBinderOffsets)) {// BpBinder没重写,返回false
- // One of our own!
- jobject object = static_cast<JavaBBinder*>(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<DeathRecipientList> drl = new DeathRecipientList;
- drl->incStrong((void*)javaObjectForIBinder);
- env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get()));
- // Note that a new object reference has been created.
- android_atomic_inc(&gNumProxyRefs);
- incRefsCreated(env);
- }
- return object;
- }
可以看出返回了android.os.BinderProxy
也就是说ServiceManagerProxy的mRemote带的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里面mObject(Bpbinder(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<Object> 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,然后通过stub的asInterface转化为IPowerManager(实际是让其带Service的Binder)
- 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;
- }
Java层Binder使用(ServiceManager)相关推荐
- 安卓高手之路之java层Binder
很多人一提到Binder就说代理模式,人云亦云的多,能理解精髓的少. 本篇文章就从设计角度分析一下java层BInder的设计目标,以及设计思路,设计缺陷,从而驾驭它. 对于[邦德儿]的理解, 从通信 ...
- 理解Android Binder机制(3/3):Java层
本文是Android Binder机制解析的第三篇,也是最后一篇文章.本文会讲解Binder Framework Java部分的逻辑. Binder机制分析的前面两篇文章,请移步这里: 理解Andro ...
- Binder源码分析之Java层(原)
前面的几节中我们介绍了Native层Binder通讯的原理和用法,那么在Java层如何使用Binder通讯呢?其原理又与Native层的Binder有什么关系呢? 与Native层的S ...
- java层 native层_Java层的ServiceManager和Native层的ServiceManager的对应过程
转自:https://blog.csdn.net/moonshine2016/article/details/54378358 参考:https://www.jianshu.com/p/9c02370 ...
- Android系统中的Binder通信机制分析(7)- Java 层的 Binder 机制
声明 其实对于Android系统Binder通信的机制早就有分析的想法,记得2019年6.7月份Mr.Deng离职期间约定一起对其进行研究的,但因为我个人问题没能实施这个计划,留下些许遗憾- 文中参考 ...
- android binder - 客户端(c++层) 调用 服务端(java层),服务端回调客户端 例子
学习了: android binder - 客户端(java层) 调用 服务端(c++层) 例子 http://blog.csdn.net/ganyue803/article/details/4131 ...
- Binder Java层实现(一):IBinder/IInterface/Binder/Stub
要点 面向对象思想的引入将进程间通信转化为通过对某个Binder对象的引用调用该对象的方法,而其独特之处在于Binder对象是一个可以跨进程引用的对象,它的实体(本地对象)位于一个进程中,而它的引用( ...
- java 通信层_Android native进程间通信实例-binder篇之——HAL层访问JAVA层的服务
有一天在群里聊天的时候,有人提出一个问题,怎样才能做到HAL层访问JAVA层的接口?刚好我不会,所以做了一点研究. 之前的文章末尾部分说过了service call 可以用来调试系统的binder服务 ...
- JAVA层HIDL服务的获取原理-Android10.0 HwBinder通信原理(九)
摘要:本节主要来讲解Android10.0 JAVA层HIDL服务的获取原理 阅读本文大约需要花费19分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的 ...
最新文章
- python制作解压工具_使用python制作一个解压缩软件
- 第5章 用户身份与文件权限
- Vue:Elementui中的Tag与页面其它元素相互交互的两三事
- Mysql中(@i:=@i+1)的作用
- python基础知识资料-Python基础知识汇总
- 系统架构设计师证书含金量_计算机专科生不能错过的两个证书,含金量比较高,出社会有益...
- nltkdata路径设置linux,NLTK data路径设置
- 利用栈解决深度搜索问题
- 未将更新安装在此计算机上,Win7用户注意!7月前没安装这个更新包,将不能再使用更新功能!...
- 使用webpack前端重构感受
- 练习四十四:整数的排序
- Memcached笔记——(四)应对高并发攻击【转】
- 【活动】完整的Java学习路径《深入理解Java核心技术》(文末送书)
- 洛伦兹吸引子 matlab,混沌蝴蝶——洛伦兹吸引子
- 为什么说百度全面降低了中国互联网体验?
- fieldtrip学习——1.坐标系介绍(ctf坐标系和acpc坐标系简介)
- opencascade 0xXXXXXXXX处最可能的异常: 0xC0000005: 写入位置 0x00000014 时发生访问冲突
- 永定城 × 奇点云 | 数字新商贸的全国样板长什么样?
- ThinkPad E40取消FN功能键设置
- CentOS系统安装(7.8.2003)
热门文章
- EnterpriseDb公司的Postgres Enterprise Manager 安装图解
- Jsoup进阶之获取指定数据
- c语言实验数据类型体会,实验1-C语言开发环境使用和数据类型、运算符、表达式-实验总结与体会...
- matlab数据取整方法
- Linux学习笔记 --组管理和权限管理
- 工作两年总结(一句话)
- NLP---将改变您在未来的沟通方式的7种 nlp 技术 (第一部分(附原始论文))
- Javascript第五章location对象第五课
- python 类函数 成员函数_python内置函数类型,如何为新类型定义成员函数?
- pycharm添加python注释头_Pycharm自动添加头注释