您当前的位置: 首页 >  Java
  • 2浏览

    0关注

    417博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

05.Binder系统:第8课第5节_Binder系统_JAVA实现_内部机制_Client端

江南才尽,年少无知! 发布时间:2019-04-11 14:33:13 ,浏览量:2

上小节讲解了Binder系统的分层,该小节我们讲解Binder系统的内部机制,在上小节我们遗留了很多问题没有接到。 1.应用程序是java编写的,binder系统是C程序,那么java程序是如何调用C程序的呢? 我们先来回到这个问题,即这个小节需要讲解的内容: 在这里插入图片描述 从上图我们可以看到: TestServer首先通过addservice向service_manager注册服务:这个时候TestServer是客户端,service_manager为服务端。 TestClient通过getService向service_manager获取服务:这个时候TestClient是客户端,service_manager为服务端 TestClient使用服务,调用sayhello:这个时候TestClient为客户端,TestServer为服务端。

下面我们查看一下addService与getService两个函数 打开TestServer.java:

public class TestServer {
	ServiceManager.addService("hello", new HelloService());
		getIServiceManager().addService(name, service, false);
		sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
			static public IServiceManager asInterface(IBinder obj)
			return new ServiceManagerProxy(obj);
        return sServiceManager;

可以知道其最后创建了一个ServiceManagerProxy,调用ServiceManagerProxy.addService(), getService也是同样,调用ServiceManagerProxy.getService()。

现在我们来查看一下ServiceManagerProxy在ServiceManagerNative.cpp中:

class ServiceManagerProxy implements IServiceManager {	
	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 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发送数据,下面我们打开IHelloService.java:

@Override public void sayhello() throws android.os.RemoteException
	mRemote.transact(Stub.TRANSACTION_sayhello, _data, _reply, 0);
@Override public int sayhello_to(java.lang.String name) throws android.os.RemoteException
	mRemote.transact(Stub.TRANSACTION_sayhello_to, _data, _reply, 0);

其上两个函数属于IHelloService.stub.Proxy类。其最后也是使用mRemote.transac传送数据。

下面是两个类的继承图示: 在这里插入图片描述 ServiceManagerProxy与IHelloService.stub.Proxy都使用mRemote.transact发送数据,所以他们被统一起来了。 我们知道数据传输的3到要素:1.源。2.目的。3.数据。 其上的mRemote可以代表目的。 对于addSevice/getSevice其中的mRemote肯定还有handle=0这个值。mRemote 是一个java BinderProxy对象。他的mobject指向c++的一个Bpbinder对象。这个Bpbinder的mHandle=0. 对于sayhello/sayhello_to,mRemote也是一个java BinderProxy对象,他的的mbject指向一个C++的Bpbinder对象,其中的handle=1,来自于getService(“hello”)。

我们首先来看看addSevice/getSevice

addSevice/getSevice

ServiceManagerProxy中mRemote的构造(用于addSevice/getSevice),其使用0直接构造一个java BinderProxy对象。打开TestServer,可以知道其使用:

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

根据上面找到ServiceManager.java文件中的addService//getSevice方法:

addService
public static void addService(String name, IBinder service) {
	getIServiceManager().addService(name, service, false);
getSevice
public static IBinder getService(String name) {
	return getIServiceManager().getService(name);
		return sServiceManager = sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());	

我们先不分析asInterface方法,分析其参数。

public static final native IBinder getContextObject();

可以知道,这是一个C或者C++实现的函数,其最终得到一个java Binderproxy对象,其成员mOject=new Bpbinder(0)在源码搜索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 },
    { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
    { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};

可以知道其对应的函数为android_os_BinderInternal_getContextObject:

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    sp b = ProcessState::self()->getContextObject(NULL);
    return javaObjectForIBinder(env, b);
    	/*使用C++的代码,调用java某个类中的构造函数,创建一个java的对象*/
    	object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
    	env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
    	return object;	
}

我们在ProcessState.cpp中找到getContextObject函数:

sp ProcessState::getContextObject(const sp& /*caller*/)
{
    return getStrongProxyForHandle(0);
    	b = new BpBinder(handle);

到这里我们知道其handle为0,其中的 new BpBinder(handle)通过 return javaObjectForIBinder(env, b)返回。

现在我们分析ServiceManagerNative.asInterface(BinderInternal.getContextObject()),在ServiceManagerNative.cpp中:

public abstract class ServiceManagerNative extends Binder implements IServiceManager
	/*obj为一个BinderProxy对象*/
	return new ServiceManagerProxy(obj);

我们进入ServiceManagerProxy的构造函数:

class ServiceManagerProxy implements IServiceManager {
    public ServiceManagerProxy(IBinder remote) {
        mRemote = remote; //其为上面创建的BinderProxy对象中的mObject指向new BpBinder
    }

下面我们看看sayhello/sayhello_to中的mRemote是怎么构造的:

sayhello/sayhello_to

打开TestClient.java:

public static void main(String args[])
	IBinder binder = ServiceManager.getService("hello");
	IHelloService svr = IHelloService.Stub.asInterface(binder);

我们先分析简单的asInterface在IHelloService文件中:

public static IHelloService asInterface(android.os.IBinder obj)
	return new IHelloService.Stub.Proxy(obj);
		/*IHelloService.Stub.Proxy的构造函数*/
		mRemote = remote;
		

其中的obj为ServiceManager.getService得到的IBinder binder。

下面分析IBinder binder = ServiceManager.getService(“hello”),我们可以猜测其返回值就是一个java BinderProxy对象,其中的mOject = new BpBinder(handel)。进入ServiceManagerNative.java:

public IBinder getService(String name) throws RemoteException {
	IBinder binder = reply.readStrongBinder();
		//parcel.java
		return nativeReadStrongBinder(mNativePtr);

看到nativeReadStrongBinder,我们可以知道其是通过c++实现,在源码中搜索nativeReadStrongBinder,可以在android_os_Parcel.cpp中找到他的实现函数

static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
	/*把java parcel对象转化为c++parcel对象*/
	/*client程序向service_manege发出getService请求,
	得到一个回复reply,他里面含有一个flat_binder_object,
	他被封装成一个C++的parcel对象*/
	
    Parcel* parcel = reinterpret_cast(nativePtr);
    if (parcel != NULL) {
        return javaObjectForIBinder(env, parcel->readStrongBinder());
    }
    return NULL;
}

可以看到其中调用了javaObjectForIBinder,他会创建一个java BinderProxy对象,其中的mObject = new BpBinder(handle)对象 在这里插入图片描述

关注
打赏
1592542134
查看更多评论
立即登录/注册

微信扫码登录

0.0420s