学习参考:http://blog.csdn.net/luoshengyang/article/details/6642463

本博文将基于Binder扩展android的系统服务,在编写实例的同时,将会对Binder机制在framework层的接口源码进行分析。

扩展的系统服务描述如下:霍金不会说话,希望Android手机帮助他说话,那么需要将说话的服务当作系统服务放到到Android系统中。实例会编写或分析如下内容:

  1. 获取Service Manager的Java远程接口的过程;
  2. 系统服务HawkingService接口的定义;
  3. HawkingService的启动过程;
  4. Client获取HawkingService的Java远程接口的过程;
1. 获取ServiceManager的Java远程接口的过程 因为系统服务全部被ServiceManager管理,所以这里将分析一下如何获取ServiceManager的Java远程接口。下面是ServiceManager相关的类图。

如图所示,ServiceManager中有个getIServiceManager方法可以返回ServiceManager的Java运程接口,利用返回的对象就可以获得ServiceManager对系统服务管理的服务了。
    private static IServiceManager getIServiceManager() {        if (sServiceManager != null) {            return sServiceManager;        }        // Find the service manager        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());        return sServiceManager;    }
跟踪代码可以看到最终要返回IServiceManager,需要往ServiceManagerProxy的构造函数中传入一个IBinder对象,这个对象是由BinderInternal.getContextObject()返回的。
public static final native IBinder getContextObject();
而getContextObject是个native方法,通过JNI返回了一个IBinder对象。具体的C++层的代码这里暂时不做分析。这样获取ServiceManager的Java远程接口就结束了。 2.系统服务HawkingService接口的定义 HawkingService提供的服务就是say,如下:
interface IHawkingService{     void say(String sth);}
我利用AIDL生成了HawkingService相关的proxy,stub代码,如下:
public interface IHawkingService extends IInterface {//Hawking Serverpublic static abstract class Stub extends Binder implements IHawkingService {private static final java.lang.String DESCRIPTOR = "com.test.IHawkingService";public Stub() {this.attachInterface(this, DESCRIPTOR);}/** * 如果是本地服务接口,将IBinder对象cast为IHawkingService并返回 * 如果不是本地服务(可能是远程服务)接口,返回IHawkingService的代理对象 */public static IHawkingService asInterface(IBinder obj) {if ((obj == null)) {return null;}IInterface iin = (IInterface) obj.queryLocalInterface(DESCRIPTOR);if (((iin != null) && (iin instanceof IHawkingService))) {return ((IHawkingService) iin);}return new IHawkingService.Stub.Proxy(obj);}public IBinder asBinder() {return this;}@Overridepublic boolean onTransact(int code, Parcel data,Parcel reply, int flags)throws RemoteException {switch (code) {case INTERFACE_TRANSACTION: {reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_say: {data.enforceInterface(DESCRIPTOR);String _arg0 = data.readString();this.say(_arg0);reply.writeNoException();return true;}}return super.onTransact(code, data, reply, flags);}//Hawking Proxyprivate static class Proxy implements IHawkingService {private IBinder mRemote;Proxy(IBinder remote) {mRemote = remote;}public IBinder asBinder() {return mRemote;}public void say(String sth) throws RemoteException {Parcel _data = Parcel.obtain();Parcel _reply = Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeString(sth);mRemote.transact(Stub.TRANSACTION_say, _data, _reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}}static final int TRANSACTION_say = (IBinder.FIRST_CALL_TRANSACTION + 0);}public void say(String sth) throws RemoteException;}
IHawkingService的服务端实现类时HawkingService,代码如下
public class HawkingService extends IHawkingService.Stub{@Overridepublic void say(String sth) throws RemoteException {System.out.println("hawking say: "+sth);}}
3. HawkingService服务的启动过程 开机时,系统服务的启动都是交给SystemServer进行处理的,SystemServer会启动一个ServerThread的线程用于启动系统服务并把启动的服务添加到ServiceManager中。
public class SystemServer{       native public static void init1(String[] args);   public static void main(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();    }}
 class ServerThread extends Thread {         ......    @Override      public void run() {          .....        Looper.prepare();          ......          try {              Slog.i(TAG, "HawkingService");              ServiceManager.addService("hawking", new HawkingService());          } catch (Throwable e) {              Slog.e(TAG, "Failure starting Hawking Service", e);          }          ......          Looper.loop();          ......      }  } 
如上述代码ServiceManager.addService("hawking", new HawkingService());,new HawkingService()是创建了一个Binder对象,下面我们就来看一下,如何创建一个Binder对象以及如何将这个进行add Service。 创建Binder对象过程:
public class Binder implements IBinder {      ......      private int mObject;      ......      public Binder() {          init();          ......      }      private native final void init();      ......  } 
new HawkingService()会调用Binder的构造函数,如上述代码,Binder的构造函数会调用一个native方法init,这个方法定义在frameworks/base/core/jni/android_util_Binder.cpp中。
static void android_os_Binder_init(JNIEnv* env, jobject clazz)  {      JavaBBinderHolder* jbh = new JavaBBinderHolder(env, clazz);      if (jbh == NULL) {          jniThrowException(env, "java/lang/OutOfMemoryError", NULL);          return;      }      LOGV("Java Binder %p: acquiring first ref on holder %p", clazz, jbh);      jbh->incStrong(clazz);      env->SetIntField(clazz, gBinderOffsets.mObject, (int)jbh);  }
可以看出init做的事情就是创建一个JavaBBinderHolder对象,并将对象地址返回给 mObjectServiceManager.addService过程
class ServiceManagerProxy implements IServiceManager {      public ServiceManagerProxy(IBinder remote) {          mRemote = remote;      }      ......      public void addService(String name, IBinder service)          throws RemoteException {              Parcel data = Parcel.obtain();              Parcel reply = Parcel.obtain();              data.writeInterfaceToken(IServiceManager.descriptor);              data.writeString(name);              data.writeStrongBinder(service);              mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);              reply.recycle();              data.recycle();      }      ......      private IBinder mRemote;  } 
addService最终的实现在ServiceManagerProxy中。上述代码data.writeStrongBinder(service) 是将Binder对象写入到Parcel包裹中,这个写入的对象service就是刚才生成的mObject地址转化过来的。具体的实现在writeStrongBinder的JNI实现中。 4.Client获取HawkingService的Java远程接口的过程 下面编写一个客户端通过ServiceManager的getService方法去获取系统服务HawkingService。
public class HawkingActivity extends Activity{        private IHawkingService hawkingService;          @Override        public void onCreate(Bundle savedInstanceState) {              hawkingService= IHawkingService.Stub.asInterface(                                ServiceManager.getService("hawking"));        hawkingService.say("Hello everyone");    }  } 
ServiceManager.getService实际上是调用了ServiceManagerProxy.getService函数。
class ServiceManagerProxy implements IServiceManager {  public ServiceManagerProxy(IBinder remote) {        mRemote = remote;    }  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;    }   .......}

更多相关文章

  1. Android常用类库包介绍
  2. Android(安卓)Context 是什么?
  3. android (三)、Activity工作原理
  4. Android通知栏微技巧,8.0系统中通知栏的适配
  5. Android系统分区简介
  6. Android: 打败system,自己监听Home键
  7. Android的异步(Thread、Handler、AsyncTask)
  8. [Android] Android中将一个图片切割成多个图片
  9. 全志A10平板上的ubuntu终极安装版,支持HDMI和平板本机LCD,全新内核

随机推荐

  1. Android* 教程:使用英特尔® 线程构建模块
  2. Android图片加载库:最全面的Picasso讲解
  3. Android入门进阶教程(10)-Xml解析
  4. Android:WebView全面总结
  5. android 6.0的变化
  6. Kivy A to Z -- 如何从Python创建一个基
  7. [置顶] 两分钟彻底让你明白Android(安卓)
  8. App 调试的几个命令实践
  9. Android浪潮
  10. Android使用Fragment实现底部导航栏