binder java_Binder java层实现原理

android使用java实现的,因此binder很多是在java中使用。此篇博客是在罗老师那边博客上节选一段,然后自己分析了下。

下面是自己写的一个aidl文件

package android.os;

interface IHelloService

{

void setVal(int val);

int getVal();

}

注意,这是一个aidl文件,编译后会生成一个IHelloService.java。我们来看一下这个文件的内容隐藏着什么奥秘,可以这么神奇地支持进程间通信。

在java中有一个aidl文件,让我们省去了很多工作,其实下了下面这段将aidl文件展开其实很c++很像。

/*

* This file is auto-generated. DO NOT MODIFY.

* Original file: frameworks/base/core/java/android/os/IHelloService.aidl

*/

package android.os;

public interface IHelloService extends android.os.IInterface

{

/** Local-side IPC implementation stub class. */

public static abstract class Stub extends android.os.Binder implements android.os.IHelloService//相当于是一个Server端,需要一个子类来继续继承它,完成接口的实现

{

private static final java.lang.String DESCRIPTOR = "android.os.IHelloService";

/** Construct the stub at attach it to the interface. */

public Stub()

{

this.attachInterface(this, DESCRIPTOR);

}

/**

* Cast an IBinder object into an android.os.IHelloService interface,

* generating a proxy if needed.

*/

public static android.os.IHelloService asInterface(android.os.IBinder obj)//和c++类似,如果在client端才去new一个proxy

{

if ((obj==null)) {

return null;

}

android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);

if (((iin!=null)&&(iin instanceof android.os.IHelloService))) {

return ((android.os.IHelloService)iin);

}

return new android.os.IHelloService.Stub.Proxy(obj);

}

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_setVal:

{

data.enforceInterface(DESCRIPTOR);

int _arg0;

_arg0 = data.readInt();

this.setVal(_arg0);

reply.writeNoException();

return true;

}

case TRANSACTION_getVal:

{

data.enforceInterface(DESCRIPTOR);

int _result = this.getVal();

reply.writeNoException();

reply.writeInt(_result);

return true;

}

}

return super.onTransact(code, data, reply, flags);

}

private static class Proxy implements android.os.IHelloService//这个内部类,相当于一个client端和C++类似

{

private android.os.IBinder mRemote;

Proxy(android.os.IBinder remote)

{

mRemote = remote;

}

public android.os.IBinder asBinder()

{

return mRemote;

}

public java.lang.String getInterfaceDescriptor()

{

return DESCRIPTOR;

}

public void setVal(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_setVal, _data, _reply, 0);

_reply.readException();

}

finally {

_reply.recycle();

_data.recycle();

}

}

public int getVal() throws android.os.RemoteException

{

android.os.Parcel _data = android.os.Parcel.obtain();

android.os.Parcel _reply = android.os.Parcel.obtain();

int _result;

try {

_data.writeInterfaceToken(DESCRIPTOR);

mRemote.transact(Stub.TRANSACTION_getVal, _data, _reply, 0);

_reply.readException();

_result = _reply.readInt();

}

finally {

_reply.recycle();

_data.recycle();

}

return _result;

}

}

static final int TRANSACTION_setVal = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);

static final int TRANSACTION_getVal = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);

}

public void setVal(int val) throws android.os.RemoteException;

public int getVal() throws android.os.RemoteException;

}

这里我们可以看到IHelloService.aidl这个文件编译后的真面目,原来就是根据IHelloService接口的定义生成相应的Stub和Proxy类,这个就是我们熟悉的Binder机制的内容了,即实现这个HelloService的Server必须继续于这里的IHelloService.Stub类,而这个HelloService的远程接口就是这里的IHelloService.Stub.Proxy对象获得的IHelloService接口。接下来的内容,我们就可以看到IHelloService.Stub和IHelloService.Stub.Proxy是怎么创建或者使用的。

三. HelloService的启动过程

在讨论HelloService的启动过程之前,我们先来看一下实现HelloService接口的Server是怎么定义的。

回忆在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务一文,我们在frameworks/base/services/java/com/android/server目录下新增了一个HelloService.java文件:

package com.android.server;

import android.content.Context;

import android.os.IHelloService;

import android.util.Slog;

public class HelloService extends IHelloService.Stub {//实现aidl文件解析后,里面的内部类

private static final String TAG = "HelloService";

HelloService() {

init_native();

}

public void setVal(int val) {

setVal_native(val);

}

public int getVal() {

return getVal_native();

}

private static native boolean init_native();

private static native void setVal_native(int val);

private static native int getVal_native();

}  这里,我们可以看到,HelloService继续了IHelloService.Stub类,它通过本地方法调用实现了getVal和setVal两个函数。我们不关心这两个函数的具体实现,有兴趣的读者可以参考

在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务一文。

有了HelloService这个Server类后,下一步就是考虑怎么样把它启动起来了。在frameworks/base/services/java/com/android/server/SystemServer.java文件中,定义了SystemServer类。SystemServer对象是在系统启动的时候创建的,它被创建的时候会启动一个线程来创建HelloService,并且把它添加到Service Manager中去。

我们来看一下这部份的代码:

class ServerThread extends Thread {

......

@Override

public void run() {

......

Looper.prepare();

......

try {

Slog.i(TAG, "Hello Service");

ServiceManager.addService("hello", new HelloService());//加入serviceManager中

} catch (Throwable e) {

Slog.e(TAG, "Failure starting Hello Service", e);

}

......

Looper.loop();

......

}

}

......

public class SystemServer

{

......

/**

* This method is called from Zygote to initialize the system. This will cause the native

* services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back

* up into init2() to start the Android services.

*/

native public static void init1(String[] args);

......

public static final void init2() {

Slog.i(TAG, "Entered the Android system server!");

Thread thr = new ServerThread();

thr.setName("android.server.ServerThread");

thr.start();

}

......

} 四. Client获取HelloService的Java远程接口的过程

前面我们在学习Android系统硬件抽象层(HAL)时,在在Ubuntu上为Android系统内置Java应用程序测试Application Frameworks层的硬件服务这篇文章中,我们创建了一个应用程序,这个应用程序作为一个Client角色,借助Service Manager这个Java远程接口来获得HelloService的远程接口,进而调用HelloService提供的服务。

我们看看它是如何借助Service Manager这个Java远程接口来获得HelloService的远程接口的。在Hello这个Activity的onCreate函数,通过IServiceManager.getService函数来获得HelloService的远程接口:

public class Hello extends Activity implements OnClickListener {

......

private IHelloService helloService = null;

......

@Override

public void onCreate(Bundle savedInstanceState) {

helloService = IHelloService.Stub.asInterface(

ServiceManager.getService("hello"));//调用自定义的helloservice,不过需要自己asInterface转成自己的接口

}

......

}至于,java调用c++的那些JNI就不分析了。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值