标签:des android blog io os 使用 ar java for
分析Java层的ServiceManager,看看Binder在Java层是如何实现的。
public final class ServiceManager { private static final String TAG = "ServiceManager"; private static IServiceManager sServiceManager;//IserviceManager是一个接口,定义了通用(公共)方法。 private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();//缓存,其值是IBinder ... public static IBinder getService(String name) { try { IBinder service = sCache.get(name);//先从缓存中查找 if (service != null) { return service; } else { return getIServiceManager().getService(name);//生成新的IBinder } } catch (RemoteException e) { Log.e(TAG, "error in getService", e); } return null; }
...
这里的ServiceManager仅仅是一种封装,其成员变量和方法都是static。从上面的sCache保存的键值对和getService的返回值类型为IBinder(与C++层的IBinder不同)可以看出,通过ServiceManager得到的是一个IBinder类型对象,通过后面的分析,实际可以看出它是BpBinder对象。
private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // Find the service manager sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());//找到IServiceManager对象,并返回 return sServiceManager; } ... /** * 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();//BinderInternale:调用native函数,返回IBinder对象 ... static public IServiceManager asInterface(IBinder obj)//传入的就是上面的那个IBinder对象,记住这是Java对象 { if (obj == null) { return null; } IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor);//从IBinder对象里查找,并转换为IServiceManager对象 if (in != null) { return in; } return new ServiceManagerProxy(obj);//如果找不到,则使用传入的IBinder对象生成一个ServiceManagePorxy对象 }
上面绕了一圈,直接从ServiceManagerProxy来看,有两方面:1,得到native层的一个某对象,并转换为IBinder,即上面的native IBinder getContextObject();2,使用获得的IBinder来生成一个ServiceManagerProxy对象。下面来看看ServiceManagerProxy的构造方法:
public ServiceManagerProxy(IBinder remote) { mRemote = remote;//mRemote是IBinder类型,这里将传入的IBinder对象保存在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的transact来传送数据 IBinder binder = reply.readStrongBinder(); reply.recycle(); data.recycle(); return binder; }
小结:调用ServiceManager的getService(),会生成一个ServiceManagerProxy对象,该对象持有一个mRemote(IBinder),通过该mRemote(它是BpBinder在Java层的代表)可以向下层发送数据。
getContextObject分析:
public static final native IBinder getContextObject();//BinderInternale:调用native函数,返回IBinder对象——对应为下面这个函数:
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) { sp<IBinder> b = ProcessState::self()->getContextObject(NULL);//走到这里:b为一个BpBinder return javaObjectForIBinder(env, b);//返回一个Java层的BinderProxy
到这里明白了,上面的mRemote持有的就是BinderProxy对象。而上面调用mRemote对象的transact()方法就是调用BinderProxy的transact方法:
public native boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException; ... 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*)//将BinderProxy转换为BpBinder env->GetIntField(obj, gBinderProxyOffsets.mObject);
...
status_t err = target->transact(code, *data, reply, flags);//调用BpBinder来与更下层通信 ...
走到这里:Java层主要就是获取Native层的BpBinder,并使用它来与下层通信。
标签:des android blog io os 使用 ar java for
原文地址:http://www.cnblogs.com/littlefishxu/p/4003445.html