Java接口源代码--System和Service Manager进程间通信--应用程序和Service Manager进程间通信

本文详细分析了Android系统中System进程和服务管理器(Service Manager)之间的通信过程,以及应用程序如何通过Java接口与Service Manager进行通信。涉及到的关键组件包括IInterface、IServiceManager、IBinder、Binder、ServiceManagerNative等。通过源代码解析,阐述了Binder机制在进程间通信的角色,包括BinderProxy、ServiceManagerProxy的创建和交互。同时,概述了Android应用程序获取Service Manager远程接口的步骤以及封装进程间通信数据的过程。
摘要由CSDN通过智能技术生成

本文参考《Android系统源代码情景分析》,作者罗升阳

一、架构代码: 

      ~/Android/frameworks/base/core/java/android/os

      ----IInterface.java (Interface)

      ----IServiceManager.java (IServiceManager)

      ----IBinder.java (IBinder)

      ----Binder.java (BinderProxy,Binder)

      ----ServiceManagerNative.java (ServiceManagerProxy,ServiceManagerNative)

      ----ServiceManager.java (ServiceManager)

      ~/Android/frameworks/base/core/jni

      ----android_util_Binder.cpp



      测试代码:(参考实现硬件访问服务和开发Android应用程序来使用硬件访问服务两篇文章

     ~/Android/frameworks/base/services/java/com/android/server

     ----SystemServer.java

      ~/Android/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os

      ----IFregService.java

      ~/Android/frameworks/base/services/java/com/android/server

      ----FregService.java

      ~/Android/packages/experimental/Freg

      ----src----shy/luo/freg----Freg.java


      uml类图如下:



二、System进程和Service Manager进程间通信

     系统进程System启动了硬件访问服务FregService,参考实现硬件访问服务http://blog.csdn.net/jltxgcy/article/details/29372453,如下:

     ~/android-2.3_r1/frameworks/base/services/java/com/android/server

     ----SystemServer.java

class ServerThread extends Thread {
	......

	@Override
	public void run() {

		......

		Looper.prepare();

		......

		try {
			Slog.i(TAG, "FregService");
			ServiceManager.addService("freg", new FregService());
		} 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();
	}
	......
}

      调用了ServiceManager的addService方法,实现如下:

      ~/Android/frameworks/base/core/java/android/os

      ----ServiceManager.java

public final class ServiceManager {
	......
	private static IServiceManager sServiceManager;
	......
	private static IServiceManager getIServiceManager() {
		if (sServiceManager != null) {
			return sServiceManager;
		}

		// Find the service manager
		sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
		return sServiceManager;
	}
	......
        public static void addService(String name, IBinder service) {
               try {
                     getIServiceManager().addService(name, service);
               } catch (RemoteException e) {
                     Log.e(TAG, "error in addService", e);
               }
        }
        ......
}


1、System进程,获取Service Manager的Java远程接口的过程

       如果其静态成员变量sServiceManager尚未创建,那么就调用ServiceManagerNative.asInterface函数来创建。在调用ServiceManagerNative.asInterface函数之前,首先要通过BinderInternal.getContextObject函数来获得一个BinderProxy对象。

     

      我们来看一下BinderInternal.getContextObject的实现:      ~/Android/frameworks/base/core/java/com/android/internal/os 

      ----BinderInternal.java

public class BinderInternal {
	......
	/**
	* Return the global "context object" of the system.  This is usually
	* an implementation of IServiceManager, which you can use to find
	* other services.
	*/
	public static final native IBinder getContextObject();
	
	......
}

     这里可以看出,BinderInternal.getContextObject是一个JNI方法,实现如下:

      ~/Android/frameworks/base/core/jni

      ----android_util_Binder.cpp

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    return javaObjectForIBinder(env, b);
}
     这里看到我们熟悉的ProcessState::self()->getContextObject函数,返回一个BpBinder对象,它的句柄值是0,即下面语句:

sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
     相当于是:
sp<IBinder> b = new BpBinder(0);
     

     在调用javaObjectForIBinder函数之前,我们先介绍jni的加载。


 
       先来看两个变量gBinderOffsets和gBinderProxyOffsets的定义。

       先看gBinderOffsets的定义:

       ~/Android/frameworks/base/core/jni

       ----android_util_Binder.cpp

static struct bindernative_offsets_t
{
    // Class state.
    jclass mClass;
    jmethodID mExecTransact;

    // Object state.
    jfieldID mObject;

} gBinderOffsets;

      简单来说,gBinderOffsets变量是用来记录上面第二个类图中的Binder类的相关信息的,它是在注册Binder类的JNI方法的int_register_android_os_Binder函数初始化的:

      ~/Android/frameworks/base/core/jni

      ----android_util_Binder.cpp

const char* const kBinderPathName = "android/os/Binder";

static int int_register_android_os_Binder(JNIEnv* env)
{
    jclass clazz;

    clazz = env->FindClass(kBinderPathName);
    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder");

    gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz);//引用java层的Binder类
    gBinderOffsets.mExecTransact
        = env->GetMethodID(clazz, "execTransact", "(IIII)Z");//引用java层Binder类的execTransact方法
    assert(gBinderOffsets.mExecTransact);

    gBinderOffsets.mObject
        = env->GetFieldID(clazz, "mObject", "I");//引用java层Binder类的mObject属性
    assert(gBinde
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值