您的位置:首页 > 编程语言 > Java开发

BinderJAVA实现client内部机制

2018-01-08 17:23 746 查看
test_server.java

函数调用

ServiceManager.addService("hello", new HelloService());


这是一个静态函数

public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} 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;
}

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);
}

创建了一个SProxy对象
看他的addService函数

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();
}

使用mRemote->transact()函数发送数据



对于addService来说mRemote是一个JavaBinderProxy对象它的mobject指向一个C++的BpBinder对象这个BpBinder的mHandle=0;是SM

SMProxy中的mRemote的构造:应该是使用0直接构造出一个java层的 BinderProxy对象。

sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());分析这个参数
public static final native IBinder getContextObject();
发现它是一个本地函数

对应在android_util_binder.cpp文件里的
static const JNINativeMethod gBinderInternalMethods[] = {
/* name, signature, funcPtr */
{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
{ "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
{ "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
{ "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};他的实现函数是
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
return getStrongProxyForHandle(0);
}

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
。。。。。。。。。。。。
b = new BpBinder(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
。。。。。。。。。。。。
}
BpBinder::BpBinder(int32_t handle)
: mHandle(handle)
, mAlive(1)
, mObitsSent(0)
, mObituaries(NULL)
BpBinder的构造函数将mHandle的值弄为传进来的0.
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);


第一句执行完返回,里面的b = new BpBinder()。//里面的nHandle= 0

jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
}
在这个函数里面调用java某个类的构造函数创建出一个java对象。
const char* const kBinderProxyPathName = "android/os/BinderProxy";
clazz = env->FindClass(kBinderProxyPathName);
gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz);

使用C代码调用newobject创建JAVA  BinderProxy对象(JAVA层Bidner代理)

它的mObject = val.get =b

参数分析完毕

再看SMNative.java

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); }最后返回的是一个SMProxy对象obj = BinderProxy对象
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
}

构造函数将mRemote = 传进来的obj = BinderProxy (其中里的mObject = BpBinder对象 里的mHandle = 0)
对于client 调用server是相似的。

IBinder binder = ServiceManager.getService("hello");
IHelloService svr = IHelloService.Stub.asInterface(binder);
public static IHelloService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof IHelloService))) {
return ((IHelloService)iin);
}
return new IHelloService.Stub.Proxy(obj);
}
private static class Proxy implements IHelloService
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
}


obj应该是一个BinderProxy对象
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;
}
    private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}

// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}


到这返回的是SMProxy,所以调用的是SMProxy的getService函数。
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;
}
public final IBinder readStrongBinder() {
return nativeReadStrongBinder(mNativePtr);
}
这是一个本地函数
在android_os_Parcel.cpp文件中

{"nativeReadStrongBinder",    "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},

他的实现函数是

static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
return javaObjectForIBinder(env, parcel->readStrongBinder());
}
return NULL;
}javaObjectForIBinder函数返回一个BinderProxy对象知道的

parcel->readStrongBinder应该是一个BpBinder对象
sp<IBinder> Parcel::readStrongBinder() const
{
sp<IBinder> val;
unflatten_binder(ProcessState::self(), *this, &val);
return val;
}
status_t unflatten_binder(const sp<ProcessState>& proc,
const Parcel& in, sp<IBinder>* out)
{
const flat_binder_object* flat = in.readObject(false);

if (flat) {
switch (flat->type) {
case BINDER_TYPE_BINDER:
*out = reinterpret_cast<IBinder*>(flat->cookie);
return finish_unflatten_binder(NULL, *flat, in);
case BINDER_TYPE_HANDLE:
*out = proc->getStrongProxyForHandle(flat->handle);
return finish_unflatten_binder(
static_cast<BpBinder*>(out->get()), *flat, in);
}
}
return BAD_TYPE;
}
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)

{

            b = new BpBinder(handle);

            e->binder = b;

            if (b) e->refs = b->getWeakRefs();

            result = b;
}

构造了BpBinder对象

所以最后mRetmote = BinderProxy对象(构造函数在Binder.java中)

它的transact函数是

public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
return transactNative(code, data, reply, flags);
}    调用本地函数在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;
}
//取出data转化成C++Parcel
Parcel* data = parcelForJavaObject(env, dataObj);
if (data == NULL) {
return JNI_FALSE;
}
//取出reply
 Parcel* reply = parcelForJavaObject(env, replyObj);
if (reply == NULL && replyObj != NULL) {
return JNI_FALSE;
}
//取出mObject就是那个BpBinder对象
IBinder* target = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
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 %" PRId32 "\n",
target, obj, code);

#if ENABLE_BINDER_SAMPLE
// 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();
}
#endif
//printf("Transact from Java code to %p sending: ", target); data->print();
//调用它的transact函数
 status_t err = target->transact(code, *data, reply, flags);
//if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
#if ENABLE_BINDER_SAMPLE
if (time_binder_calls) {
conditionally_log_binder_call(start_millis, target, code);
}
#endif

if (err == NO_ERROR) {
return JNI_TRUE;
} else if (err == UNKNOWN_TRANSACTION) {
return JNI_FALSE;
}

signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
return JNI_FALSE;
}
然后进入到了IPC层使用BpBinder.cpp的C++函数。
ioctl发送数据
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android Binder系统