Android访问硬件常用的两种方式:通过JNI接口直接访问、通过Android硬件访问服务
通过JNI接口直接访问
Android应用程序通过loadLibrary函数加载C库,C库被加载时里面的JNI_Onload函数被调用,该函数注册了本地方法,来访问硬件驱动程序,从而控制硬件 。
Android硬件访问服务
应用程序只有systemserver能够访问硬件,其他的APP发送硬件访问请求给systemserver,统一管理。
1. Android系统起来后会先运行到SystemServer,会去load C库
frameworks\base\services\java\com\android\server\SystemServer.java
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
run方法里,load android_servers这个C库,对应的是onload.cpp
// Initialize native services.
System.loadLibrary("android_servers");
2. onload.cpp里面会有个JNI_OnLoad方法,注册很多个c++实现的service
frameworks\base\services\core\jni\onload.cpp
比如:register_android_server_VibratorService(env);
对应JNI文件:frameworks\base\services\core\jni\com_android_server_VibratorService.cpp
这些硬件对应的文件主要用来通过jniRegisterNativeMethods注册本地方法
static JNINativeMethod method_table[] = {
{ "vibratorExists", "()Z", (void*)vibratorExists },
{ "vibratorOn", "(J)V", (void*)vibratorOn },
{ "vibratorOff", "()V", (void*)vibratorOff }
};
int register_android_server_VibratorService(JNIEnv *env)
{
return jniRegisterNativeMethods(env, "com/android/server/VibratorService",
method_table, NELEM(method_table)); //注册本地方法
}
3. JNI文件(cpp)包含了HAL层头文件,本地方法调用了HAL层的接口,增加HAL层的好处
a. 容易修改,修改JNI文件需要编译整个系统
b. HAL层可以编译成so文件,出于保密
4. 系统起来后SystemServer通过前面加载了C库后,会调用startOtherServices();
// Initialize native services.
System.loadLibrary("android_servers");
...
// Start services.
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
SystemServer进程通过startOtherServices()方法分别实例化各个service,然后通过addService告诉 servicemanager进程(frameworks\base\core\java\android\os\ServiceManager.java),servicemanager进程管理了系统里面的所有服务。
Slog.i(TAG, "Vibrator Service");
vibrator = new
VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
service类中会调用到native方法,比如:
frameworks\base\services\core\java\com\android\server\VibratorService.java
native static boolean vibratorExists();
native static void vibratorOn(long milliseconds);
native static void vibratorOff();
frameworks\base\core\java\android\os\IVibratorService.aidl
编译后生成
out/target/common/obj/JAVA_LIBRATIES/framework_intermediates/src/core/java/android/os/IVibratorService.java
实现步骤:
a. 实现HAL层,供com_android_server_VibratorService.cpp调用
b.实现com_android_server_VibratorService.cpp 注册本地方法,供VibratorService.java使用
c. 修改systemservice.java
addService
d. VibratorService.java 调用本地(native)函数
e. 实现aidl接口文件,编译后系统会自动产生IVibratorService.java接口文件,给APP直接使用
f. APP调用
private final IVibratorService mService;
mService = IVibratorService.Stub.asInterface(ServiceManager.getService("vibrator"));
mService.hasVibrator();
系统工作流程:
a. VibratorService.java实现了IVibratorService.java文件里的接口,调用到了native方法
b. 系统起来后SystemServer进程通过startOtherServices()方法将VibratorService添加到servicemanager进程中。
c. APP调用aidl文件里面的接口,向servicemanager 发请求ServiceManager.getService。
d. mService.hasVibrator();不会直接调用到CPP函数,而是将请求发送给VibratorService.java,由VibratorService统一访问硬件。