android系统学习笔记三
第四章 android 的底层库和程序
知识点:
Android.mk的书写规则
在android中增加可执行程序、动态库、和静态库的方法
Init.rc 启动角本的使用方法
Binder机制的工作原理
使用binder在程序中构建IPC的方法
Android的系统进程
底层库和程序的结构
1 增加本地程序和库的方法
要增加的库和程序跟路径没有关系,只和它们的android.mk文件有关系
Android.mk 和makefile 有所不同,android.mk主要包含一些系统公共有宏
android .mk中选项的路径
Build/core/config.mk
各个选项的默认值
Build/core/base_rulles.mk
编译程序
1 在android.mk中编译一个可执行程序的模板
#Test Exe
LOCAL_PATH:=${call my-dir}
Include ${CLEAR_VARS}
LOCALL_SRC_FILES:=\main.c 源文件(相对于当前的目录)
LOCAL_MODULE:=test_exe 最终生成可执行文件的名称
#LOCAL_MODULE:= 模块最终的名称
#LOCAL_C_INCLUDES:= 需要包含的头文件路径
#LOCAL_STATIC_LIBRARIES:= 需要连接的静态库(*.a)
#LOCLA_SHARED_LIBRARIES:= 需要连接的动态库(*.so)
Include ${BUILD_EXECUTABLE} 以一个可执行程序的方式进行编译
2 编译一个静态库(归档文件)的模版
#Test Static lib
LOCAL_PATH=${call my-dir}
Include ${CLEAR_VARS}
LOCAL_SRC_FILES:=\helloworld.c
LOCAL_MODULE:=libtest_static 最终生成静态库的名称是libtest_static.a
#LOCAL_C_INCLUDES:=
#LOCAL_STATIC_LIBRARIES:=
#LOCAL_SHARED_LIBRAIES:=
Include ${BUILD_STATIC_LIBRARY} 编议一个静态库
3 android.mk中编译一个动态库(共享库)的模版
#Test shared lib
LOCAL_PATH:=${cal my-dir}
Include ${CLEAR_VARS}
LOCAL_SRC_FILES:=\helloworld.c
LOCAL_MODULE:=libtest_shared 最终生成动态库文件的名称是libtest_shared.so
TARGET_PRELINK_MODULE:=false
#LOCAL_C_INCLUDES:=
#LOCAL_STATIC_LIBRARIED:=
#LOCAL_SHARED_LIBRARIES:=
Include ${BUILD_SHARED_LIBRARY} 编译动态库
注:android.mk中不需要对c源文件和c++源文件进行区分,统一加入LOCAL_SRC_FILES中即可
可执行程序、静态库和动态库生成的编译结果分别存放在以下的目录中:
Out/target/produce/generic/obj/EXECUTABLE
Out/target/product/generic/obj/STATIC_LIBRARY
Out/target/product/generic/obj/SHARED_LIBRARY
每个模块的目标文件夹分别为:
可执行程序:{xxx}_intermediates
静态库: {xxx}_static_intermediates
动态库:{ xxx}_shared_intermediates
{xxx}为模块中LOCAL_MODULE中所定义的名称,可执行程序和动态库,一般在LINK子目录中是带有符号的库(没有经过符号剥离)
编译过程中,可以编译目标机的内容,也可以编译主机的内容
.以下是编译目标机内容
以下是编译主机的内容
Android.mk中可以指定最后的目标安装路径
LOCAL_MODULE_PATH 目标路径
LOCAL_UNSTRIPPED_PATH 没有经过符号剥离的目标路径
安装到不同的系统路径的方式:
LOCAL_MODULE_PATH:={TARGET_ROOT_OUT}
LOCAL_UNSTRIPPED_PATH:=${TARGET_ROOT_OUT_UNSTRIPPED}
TARGET_ROOT_OUT 根文件系统
TARGET_OUT system文件系统(默认) 如果不使用local_module_path指定路径
TARGET_OUT_DATA: data文件系统
安装程序
Android.mk中,进行目录和安装程序的示例
LOCAL_PATH:=${call my-dir}
Include ${CLEAR_VARS}
Copy_from:=\A.txt \B.txt 将当前目录下的a和b复制到system/text下
Copy_to:=${addprefix${TRAGET_OUT}/txt,${copy_from}}
${copy_to}:PRIVATE_MODULE:=txt
${copy_to}:${TARGET_OUT}/txt/% :${LOCAL_PATH}/%|${ACP}
${transform-prebuilt-to-target}
ALL_PREBUILT=${copy_to}
DIRS:=${addprefix $ (TARGET_OUT)/,\txt\} 在system目录下创建txt目录
${DIRS}:
@echo Directory:$@
@mkdir -p$@
标准c/c++库bionic
源码和头文件在以下的目录中 : bionic/
Bionic支持标准c/c++库的绝大部分功能,支持数学库和NPTL线程库,实现了自已的Linker和loader , 用于动态库的创建和加载
加入了log的底层支持,还实现了一套property系统, 是android 全局变量的存储区域,是用共享内存的方式来实现
C语言工具库libcutils -- 本地最基础的库
工具库头文件的路径是: system/core/include/cutils
工具库源文件的路径:system/core/libcutils
工具库编译的结果: libcutils.so
工具库中主要头文件如下:
Ashmem.h 匿名共享内存的接口
Atomic.h 原子操作接口
Array.h 定义一个可以动态改变大小的数组
Threads.h 线程接口,定义线程和相关的互斥量
Sockets.h android的套接字接口
Properties.h android属性系统接口
Log.h log的信息接口 定义了logv logd logi logw loge
Mq.h 消息对列接口
Hashmap.h 定义哈希表的工具
数组功能 分配内存来实现 /dev/ashmem的驱动来实现
套接字 linux标准的Socket来实现
线程 调用标准的Posix线程pthread来实现
Log输出 调用并连接liblog库
Init 可执行程序
Init 进程是android 启动后,系统执行的第一个程序,以守护进程的方式运行
功能:
设备管理
解析启动脚本init.rc
执行启动脚本的基本功能
执行启动脚本中的各种服务
Init进程的代码路径为:system/core/init
Init处理完一系列操作后,将进入一个循环(进行设备处理) parse_config_file("/init.rc")
Log 的输出 首先调用load_565rle_image() 打开"/initlogo.rle"文件,通过写调用写framebuffer驱动程序的方式,输出到屏幕上
如果要使用开机画面,就需要构造一个“/initlogo.rle”文件,这是一个RGB565格式的纯数据文件.
设备管理的内容在device.*中定义,分为初始化阶段和运行阶段两部分, 基本的处理过程是通过读取Linux的uevent事件, 从而获取linux内核中发生的事件, 然后进行创建设备节点
Device_init() 的返回值在main函数中使用, 进行pull操作,用于动态创建设备节点、删除设备节点
Make_device()用于动态创建文件系统中驱动的设备节点,主要调用mknod()函数
程序启动后将调用handle_device_event()函数, 然后调用make_device()用于创建各个设备
Graphics 子系统用于创建Framebuffer的设备节点,默认情况下是在/dev下.在android 中
更改到/dev/graphics目录中
系统支持的设备在devperms数组中定义,这个数组的类型是perms
如果在系统中需要增加新的驱动程序,并且设备节点需要自动创建,则需要在devperms
数组中增加内容
启动脚本init.rc
在系统初始化过程中进行一些简单的初始化操作
启动脚步本的路径: system/core/rootdir/init.rc
语法:
Commands:命令
Action 动作
Triggers 触发条件
Service 服务
Service 服务名称 s可执行程序
Socket
User
Group
Oneshot 表示该服务只启动一次,如果没有这个可执行程序会一直存在如果
可执行程序被杀死,则会得新启动
Options 选项
Properties 属性
Shell工具
Android 中shell界面供开发调试使用,需要启动一个名称为console的服务.
Console可执行程序的路径为console
Shell的功能是由sh程序( 控制台)和工具箱(具体的命令)两部分组成
Sh程序 作为守护进程运行 即android 的shell终端
Sh代码的路径:system/core/sh
入口文件是main.c 执行后调用cmdloop()函数进入命令的循环中
Builtin.h定义类内建命令的格式
Builtin.c定义了内建命令的数组(命令名称对应函数指针)
builtincmd内建命令数组
Splbltincmd分割功能的内建命令数组
Sh程序使用系统的第一个终端(ttty0)作为输入输出设备(不支持tab键自动补全)
命令工具箱
Toolbox 提供了在shell界面下执行的各个命令行命令
Toolbox的代码路径为: system/core/toolbox
入口文件为:toolbox.c
如果要增加新命令只需要增加一个文件,实现类似形式的函数,并在当前目录的
Android.mk中加入命令的名称,(toobox的android .mk 自动找到源文件加入编译,并且自动生成tools.h头文件)
C++工具库libutils
Libutils头文件的路径:frameworks/base/include/utils
Libutils源文件的路径:frameworks/base/libs/utils
编译的结果是:libutils.so
Libutils中基本的主要头文件包括:
Error.h:定义表示错误码代码的宏
Endian.h:定义表示大小端的宏?
Misc.h:字符串和文件相关的功能函数
TextOutput.h:定义文本输入的基类
bufferedTextOutput.h: 是一个textOutput的实现
Pipe.h:定义管道类pipe;
Buffer.h:定义内存缓冲区域的类
List.h:定义链表的模版类
SharedBuffer.h:定义类SharedBuffer表示共享内存
String16.h:定义表示双字节字符串的类String16
String8.h:定义表示单字节字符串的类String8
VectorImpl.h:定义表示向量的类VectorImpl:
Vector.h: 定义继承Vector.定义继承vectorImpl类模版
SortedVector.h:定义排序向量的模版
keyedVector.h: 定义使用关键字的向量模版
Threads.h:定义线程相关的类
Socket.h:定义套接字相关的类
Timers.h:定义时间相关的函数和定时器
ZipEntry.h: 与zip功能相关的类
Binder(libbinder.so)
用于进程间的通信(IPC),类似于openBinder(传统的IPC机制还有Socket 和pipe
D-BUS)
Native 部分的binder实现
Binder基本架构
1.驱动层 dev/binder
2 驱动适配层 IPCThreakState.cpp和ProcessState.cpp,
3 Binder核心框架层 IBinder(IPC传输介质)两个子类BBinder和BpBinder
IInterface表示需要使用ipc的一个接口
4 Binder 框架层
5 Binder 服务和客户端实现层
Binder服务器端和客户端
Binder 的实现基础是运行与kernel空间的binder驱动
路径为 frameworks/base/include/binder
Frameworks/base/libs/binder
在native层中,其实也就是实现第四层和第五层 主要使用的头文件是IInterface.h
IInterface中有两个宏,DECLARE_META_INTERFACE()
为类自动声明asInterface()和getInterfaceDescriptor()两个函数
IMPLEMENT_META_INTERFACE()
使用这两个宏可以为继承IInterface的类节省很多代码
BnInterface是一个类模版
Binder系统的使用,需继承IInterface 和BnInterface(在IInterface中)两个类,实现进程间
的通信
/fremework/base/libs/ IpermissionController.h
IPermissionController.cpp
Libutils中的其他内容
Imemory.h 中定义了:ImemoryHeap 表示一块堆上的内存
Imemory 表示一块任意使用的内存
MemoryHeapBase 是IMemoryHeap接口的一个实现
MemoryBase 是IMemory接口的一个实现
Android 的系统进程
可以通过adb shell ps进行查看
几个重要系统进程 /init /system/bin/servicemanager /system/bin/mediaserver
System_server 和zygote
Servicemanager: 是Binder的服务管理器守护进程,所有binder机制的核心,所有Binder服务都通过他进行注册 他是一个本地应用
路径是:frameworks/base/cmds/servicemanager
运行流程:打开binder 驱动---->成为服务器管理进程------>进入binder_loop等待请求
服务的实现
以mediaPlay为例 ImediaPlayService
框架部分
frameworks/base/include/media/IMediaPlayerService.h
/frameworks/base/media/libmedia/IMediaPlayService.cpp
服务器部分
/frameworks/base/media/libmediaplayerservice/MediaPlayService.h
/frameworks/base/media/libmediaplayerservice/MediaPlayerService.cpp
客户端调用者
/frameworks/base/media/libmediaplayerservice/
建立服务的守护进程 media_server
/frameworks/base/media/mediaserver/main_mediaserver.cpp
在进程中增加服务是和servicemanager有关系的
守护进程,有名称的服务,使用binder框架架构的接口 三者之间的关系是
Zygote
通过init进程启动, 是android 运行时非常核心的部分,zygote 首先启动system_server这是大多数服务的守护进程,之后所有的Android应用程序也是由它创建
第五章 android 的java 虚拟机和java环境
Dalvik是android 的虚拟机,内容在android 中是一个独立的代码路径 dalvik/,其中包含了目标机和主机的内容
Dex工具库和虚拟的实现 (纯c语言写的实现库)
Dex工具库的目录是dalvik/dex 最终生成静态库libdex.a
虚拟机的实现库 dalvik/vm 最终生成libdvm.so(dalvik虚拟机)
虚拟机的可执行程序 dalvik/dalvikvn
核心库
Libcore的主要编译结果:
Libjavacore.a 生成java核心静态库
Core.jar 最终放置在文件系统的/system/framework目录中
目录结构如下:
Classes.dex为主体的dalvik可执行格式的字节码,java和org目录下分别是java和org这两个包中某些类包含的一些属性
Mativehelper库
是一个工具库,用于注册java本地调用的函数.(在其他代码需要使用jni从本地层向java层提供功能时使用该库)
代码路径为:dalvik/libnativehelper
Nativehelper库的头文件路径为
libnativehelper/include/nativehelper/jni.h 基于jni标准的头文件
Libnativehelper/include/nativehelper/JNIHelp.h 提供注册功能的头文件
Android 的java的程序环境 (核心包目录frameworks/base/core/java)
Java 类的代码主要在frameworks/base中
主体部分将生成frameworks.jar 包 最终放置在目标文件系统的system/framework中
Java框架部分的内容
frameworks/base/graphics/java 图形部分
frameworks/base/media/java 媒体部分
frameworks/base/opengl/java openGL部分
frameworks/base/wifi/java WiFi部分
基中资源文件frameworks/base/core/res也被生成一个jar包, framework-res.apk
Android 系统API(框架层和应用层的接口)
API 的描述文件包含在frameworks/base/api目录中,主要是current.xml
例
Android.app包中的类Activity 其代码路径为android/app/Activity.java
对应current.xml的描述如下:
<package name="android.app"> // 包内容
<class name="Activity" //类内容
extends="android.view.ContextThemeWrapper"
abstract="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<implements name="android.content.ComponentCallbacks"> //类实现的内容
</implements>
<implements name="android.view.KeyEvent.Callback">
</implements>
<implements name="android.view.LayoutInflater.Factory">
</implements>
<implements name="android.view.View.OnCreateContextMenuListener">
</implements>
<implements name="android.view.Window.Callback">
</implements>
<constructor name="Activity" // 构造函数的内容
type="android.app.Activity"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</constructor>
<method name="addContentView" //方法
return="void"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="view" type="android.view.View"> //参数
</parameter>
<parameter name="params" type="android.view.ViewGroup.LayoutParams">
</parameter>
</method>
<method name="closeContextMenu"
return="void"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</method>
<method name="closeOptionsMenu"
return="void"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</method>
<method name="createPendingResult"
return="android.app.PendingIntent"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="requestCode" type="int">
</parameter>
<parameter name="data" type="android.content.Intent">
</parameter>
<parameter name="flags" type="int">
</parameter>
</method>
<method name="dismissDialog"
return="void"
abstract="false"
native="false"
synchronized="false"
static="false"
final="true"
deprecated="not deprecated"
visibility="public"
>
<parameter name="id" type="int">
</parameter>
</method>
<method name="dispatchKeyEvent"
return="boolean"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="event" type="android.view.KeyEvent">
</parameter>
</method>
<method name="dispatchPopulateAccessibilityEvent"
return="boolean"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="event" type="android.view.accessibility.AccessibilityEvent">
</parameter>
</method>
........................
<field name="DEFAULT_KEYS_DIALER" //常量
type="int"
transient="false"
volatile="false"
value="1"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="DEFAULT_KEYS_DISABLE"
type="int"
transient="false"
volatile="false"
value="0"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="DEFAULT_KEYS_SEARCH_GLOBAL"
type="int"
transient="false"
volatile="false"
value="4"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="DEFAULT_KEYS_SEARCH_LOCAL"
type="int"
transient="false"
volatile="false"
value="3"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="DEFAULT_KEYS_SHORTCUT"
type="int"
transient="false"
volatile="false"
value="2"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="FOCUSED_STATE_SET"
type="int[]"
transient="false"
volatile="false"
value="null"
static="true"
final="true"
deprecated="not deprecated"
visibility="protected"
>
</field>
<field name="RESULT_CANCELED"
type="int"
transient="false"
volatile="false"
value="0"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="RESULT_FIRST_USER"
type="int"
transient="false"
volatile="false"
value="1"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="RESULT_OK"
type="int"
transient="false"
volatile="false"
value="-1"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<interface name="View.OnClickListener" //接口
abstract="true"
static="true"
final="false"
deprecated="not deprecated"
visibility="public"
>
在编译时,如果源代码和current.xml不一致时,可以使用以下命令更新:
Make update-api
Jni的使用 (java native interface ) ---- java本地接口
JNI 的架构
Android 中主要JNI代码在以下路径中:framework/base/core/jni 最终编译生成库
System/lib/Libandroid_runtime.so
媒体部分的jni在目录frameworks/base/media/jni中,编译成:libmedia_jni.so
在android 中实现JNI库,需要动态连接libnativehelper.so
JNI实现方式
JNI的核心是JNINativeMethod结构体, 在jni.h中定义
在框架层使用JNI
android.util.Log的情况:
public final class Log {
public static native boolean isLoggable(String tag, int level);
}
android_util_Log.cpp的方法列表
static JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{ "isLoggable", "(Ljava/lang/String;I)Z", (void*) android_util_Log_isLoggable },
{ "println_native", "(IILjava/lang/String;Ljava/lang/String;)I", (void*) android_util_Log_println_native },
};
int register_android_util_Log(JNIEnv* env)
{
jclass clazz = env->FindClass("android/util/Log");
if (clazz == NULL) {
LOGE("Can't find android/util/Log");
return -1;
}
levels.verbose = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "VERBOSE", "I"));
levels.debug = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "DEBUG", "I"));
levels.info = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "INFO", "I"));
levels.warn = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "WARN", "I"));
levels.error = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "ERROR", "I"));
levels.assert = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "ASSERT", "I"));
return AndroidRuntime::registerNativeMethods(env, "android/util/Log", gMethods, NELEM(gMethods));
}
};
在apk中实现JNI
Jni 示例程序的路径为:
Development/samples/SimpleJNI
系统服务的java部分
Binder
Java层同样提供了一套Binder的相关函数,实现在:
/frameworks/base/core/java/android/os
/frameworks/base/core/java/com/android/internal/os
/frameworks/base/core/jni
Java层的核心是binder---->IBinder----->binderProxy 这样一个三角关系
Native中 BBinder--->IBinder---->BpBinder
Java层中aidl 工具来辅助实现Binder,只需要定义接口XXX.aidl 编译器就会生成
IXXX. 客户端IXXX.stuv.Proxy和服务器端IXXX.Stub
ServiceManager ( 服务管理的服务器端)
主要分析java框架中serviceManager客户端的实现,也就是IServiceManager接口的java实现
serviceManagerNative.java
serviceManager.java
serviceManager.java
IServiceManager.java
ServiceManager的方法
public final class ServiceManager {
private static final String TAG = "ServiceManager";
private static IServiceManager sServiceManager;
private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();
private static IServiceManager getIServiceManager() { }
public static IBinder getService(String name) { }
public static void addService(String name, IBinder service) { }
public static IBinder checkService(String name) { }
public static String[] listServices() throws RemoteException { }
public static void initServiceCache(Map<String, IBinder> cache) { }
}
例如:
1. armManagerService 的调用者
代码路径为 :/frameworks/base/core/java/android/app
package android.app;
import android.app.PendingIntent;
/**
* System private API for talking with the alarm manager service.
*
* {@hide}
*/
interface IAlarmManager {
void set(int type, long triggerAtTime, in PendingIntent operation);
void setRepeating(int type, long triggerAtTime, long interval, in PendingIntent operation);
void setInexactRepeating(int type, long triggerAtTime, long interval, in PendingIntent operation);
void setTime(long millis);
void setTimeZone(String zone);
void remove(in PendingIntent operation);
}
2. Service库中alarmManagerService
public void set(int type, long triggerAtTime, PendingIntent operation) { }
public void setRepeating(int type, long triggerAtTime, long interval,
PendingIntent operation) { }
public void setInexactRepeating(int type, long triggerAtTime, long interval,
PendingIntent operation) {}
public void setTime(long millis) { }
public void setTimeZone(String tz) { }
public void remove(PendingIntent operation) { }
public void removeLocked(PendingIntent operation) {}
private void removeLocked(ArrayList<Alarm> alarmList,
PendingIntent operation) { }
3. 增加服务
在 /frameworks/base/services/java/com/android/server/SystemServer.java中
Slog.i(TAG, "Alarm Manager");
AlarmManagerService alarm = new AlarmManagerService(context);
ServiceManager.addService(Context.ALARM_SERVICE, alarm);
4. 得到接口
在/frameworks/base/core/java/android/app中
private AlarmManager getAlarmManager() {
synchronized (sSync) {
if (sAlarmManager == null) {
IBinder b = ServiceManager.getService(ALARM_SERVICE);
IAlarmManager service = IAlarmManager.Stub.asInterface(b);
sAlarmManager = new AlarmManager(service);
}
}
return sAlarmManager;
}
系统进程
主要是对zygote的分析, 它是通进init进程读取init.rc启动的
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
对应的可执行文件
/frameworks/base/cmds/app_process/app_main.c通过runtime:start开启整个初始化流程
首先是 开启java虚拟机 app_process 联接一个名为libandroid_runtime.so的动态库 , 再连接
Libdvm.so由它调用虚拟机
/frameworks/base/core/java/com/android/internal/os/ZygoteInit完成初始化操作
ZygoteInit.main()会完成一次分裂,这个分裂出来的线程(system_server)继续进行java 框架的初始化工作,通过startSystemServer()方法来完成,继续调用handleSystemServerProcess(parsedArgs) 传递参数com.android .server.SystemServer 通过RuntimeInin.zygooteInit--->systemServer.main----->systemServer.init1----->systemServer.init2
代码如下:
private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003",
"--capabilities=130104352,130104352",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
/*
* Enable debugging of the system process if *either* the command line flags
* indicate it should be debuggable or the ro.debuggable system property
* is set to "1"
*/
int debugFlags = parsedArgs.debugFlags;
if ("1".equals(SystemProperties.get("ro.debuggable")))
debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
}
return true;
}