`
willsunforjava
  • 浏览: 168565 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

通过Android Binder拓展系统服务

 
阅读更多

学习参考: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 Server
	public 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;
		}

		@Override
		public 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 Proxy
		private 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{

	@Override
	public 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对象,并将对象地址返回给mObject
ServiceManager.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;
    }
   .......
}
 
  • 大小: 9.2 KB
分享到:
评论

相关推荐

    基于Android二维码相机系统构建

    具体来说,系统设计可以分为客户端和服务端两大部分,它们之间通过Android的进程间通信机制Binder进行交互。 ##### 2. 主要组件分析 - **Camera.java**:位于`packages/apps/Camera/src/com/android/camera/`目录...

    深入理解Android:卷I--详细书签版

     笔者认为,本书最大的特点在于,较全面、系统、深入地讲解了Android系统中的几大重要组成部分的工作原理,旨在通过直接剖析源代码的方式,引领读者一步步深入于诸如Binder、 Zygote、Audio、Surface、Vold、Rild...

    Android底层架构介绍与内幕分析

    【Android底层架构介绍与内幕分析】 Android作为全球最流行的移动操作系统之一,其底层架构的深入理解和分析对于...同时,对移植过程的了解有助于开发者将Android系统拓展到更多种类的硬件设备上,实现更广泛的应用。

    深入理解Android卷1全

    1.1.1 Android系统架构 / 2 1.1.2 本书的架构 / 3 1.2 搭建开发环境 / 4 1.2.1 下载源码 / 4 1.2.2 编译源码 / 6 1.3 工具介绍 / 8 1.3.1 Source Insight介绍 / 8 1.3.3 Busybox的使用 / 11 1.4 本章小结 / 12 第2章...

    Android应用源码之SensorSample-IT计算机-毕业设计.zip

    这涉及到了Android的Binder机制和Service组件,理解这部分代码有助于掌握Android系统服务的实现方式。 其次,UI界面的设计也是SensorSample的一个重要部分。通常,开发者会使用Android的布局管理器(如LinearLayout...

    《深入理解Android》卷Ⅰ

    1.1.1 Android系统架构 1.1.2 本书的架构 1.2 搭建开发环境 1.2.1 下载源码 1.2.2 编译源码 1.3 工具介绍 1.3.1 Source Insight介绍 1.3.3 Busybox的使用 1.4 本章小结 第2章 深入理解JNI 2.1 JNI概述 2.2 学习JNI...

    Node.js-DroidPlugin是360手机助在Android上实现的插件机制

    它可能使用Binder、AIDL等Android原生机制,或者使用自定义的消息传递方式。 - **插件的加载与管理**:DroidPlugin框架会扫描特定目录下的APK文件,识别出可作为插件的应用,然后通过反射等技术进行加载和启动。 ...

    Service的常见用法分析源码

    Service是Android系统中的一个重要组件,主要用于执行长时间运行的操作或者在后台提供服务。在这个主题中,我们将深入探讨Service的常见用法,包括其生命周期、绑定方式以及Service与Activity之间的通信方式。 首先...

    百度地图开发java源码-Android-Core-Realm:成为一名优秀的Android开发者你需要知道什么

    因此,为了更好将各个知识层面的知识体系更好融合在一起,笔者创建了Android-Core-Realm这个项目,希望带领读者掌握Android系统架构中各个核心技能。 OkHttp与Retrofit是当前主流网络请求框架,view的绘制是我们...

    HermesEventBus,在进程之间使用EventBus的库,在IPC或插件开发中很有用。.zip

    Android系统默认限制了不同进程间的直接通信,需要通过特定的IPC机制来实现,如Binder、AIDL、ContentProvider、Intent等。HermesEventBus就是针对这些机制进行优化,以适应EventBus在多进程环境下的需求。通过...

    MultiType.pdf

    2. **全面支持**:它内置了类型-View的复用池系统,支持 `RecyclerView`,可以轻松扩展新的类型到列表中。 3. **灵活性高**:几乎所有的组件都可以被替换或继承定制,采用面向接口/抽象编程的方式。 4. **纯粹职责**...

Global site tag (gtag.js) - Google Analytics