能够添加驱动,能够添加工具,能够添加启动服务,现在我们添加供APP应用调用的服务。
先了解下服务,控制台输入service list查看服务,查看文件夹frameworks/base/services下内容。然后看罗升阳大神的博客Android硬件抽象层(HAL)概要介绍和学习计划。
根据博客步骤下面开始编写自己定义的service,详细参考博客,这里不贴源码,就说下大概步骤和分析下android层次。
第一步 编写Linux内核驱动程序
1.1 编写驱动
1.2 修改Kconfig和Makefile文件
第二步 增加硬件抽象层(HAL)模块访问Linux内核驱动程序
2.1 编写HAL层头文件,放置目录hardware/libhardware/include/hardware
定义设备结构体,定义接口函数,文件句柄
2.2 编写HAL层C文件,放置目录hardware/libhardware/modules/radio
定义device_open,device_close,并实例化接口函数,通过ioctl(dev->fd,*,*)实现用户层数据到底层驱动。
2.3 修改驱动ioctl文件读写权限,启动init.rc中/dev/fmsi4754 0666 root root
2.4 添加编译规则,放置目录hardware.libhardware.modules.radio下Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_SRC_FILES := radio.c
LOCAL_MODULE := radio.default
include $(BUILD_SHARED_LIBRARY)
编译mmm hardware/libhardware/modules/radio
第三步 硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
3.1 编写JNI接口,放置目录 frameworks/base/services/jni
/*JNI方法表*/
static const JNINativeMethod method_table[] = {
{"init_native", "()Z", (void*)radio_init},
{"openFM_native", "()V", (void*)radio_open_fm},
{"closeFM_native", "()V", (void*)radio_close_fm},
***
***
***
};
/*注册JNI方法*/
int register_android_server_RadioService(JNIEnv *env) {
return jniRegisterNativeMethods(env, "com/android/server/RadioService", method_table, NELEM(method_table));
}
方法表"openFM_native", "()V", (void*)radio_open_fm中openFM_native是接口,函数是无输入参数、输出为void,对应的调用是radio_open_fm
3.2 注册JNI,修改frameworks/base/services/jni的onload.cpp,register_android_server_RadioService函数声明
3.3 编译中添加源文件,修改 frameworks/base/services/jni 目录下的 Android.mk,LOCAL_SRC_FILES:= \下面追加com_android_server_RadioService.cpp \
编译mmm frameworks/base/services/jni
第四步 Application Frameworks层增加硬件访问服务
4.1 定义了服务接口,放置目录frameworks/base/core/java/android/os
4.2 编译写入服务接口
修改frameworks.base文件中的Android.mk,LOCAL_SRC_FILES:= \下面追加core/java/android/os/IRadioService.aidl \生成相应的IRadioService.Stub接口
编译mmm frameworks/base
4.3 编写java服务文件,放置目录frameworks/base/services/java/com/android/server
4.4 启动加载服务,修改frameworks/base/services/java/com/android/server文件中的SystemServer.java
try {
Slog.i(TAG, "Radio Service");
ServiceManager.addService("radio", new RadioService());
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Radio Service", e);
}
编译mmm frameworks/base/services/java
5.服务接口的使用
生成的库在android\out\target\common\obj\JAVA_LIBRARIES\services_intermediates
\android\out\target\common\obj\JAVA_LIBRARIES\framework-base_intermediates
在APP中调用
import android.os.IRadioService;
private IRadioService radioService = null;
radioService = IRadioService.Stub.asInterface(ServiceManager.getService("radio"));
int val = radioService.getVOL();
总结
现在看看分层
右边图是网上找的,android层次基本体现出来了。
linux内核以及驱动只有最底下一层。
JNI属于倒数第二层,android运行时库与C/C++本地库需要JNI方式调用与传递数据。
android系统,用虚拟机搭建一个平台,在此平台上可以运行APP而无视底层架构。可知android系统的研发大部分工作在驱动和HAL层。
工具根据其功能可分在Application Frameworks层,或是C/C++本地库层。它们只是小程序。
init读取init.rc文件来启动Dalvik虚拟机,给它分层无意义。
后面分析android系统的日志系统。