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

 编译程序 

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    将当前目录下的ab复制到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线程库,实现了自已的Linkerloader , 用于动态库的创建和加载

加入了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.*中定义,分为初始化阶段和运行阶段两部分基本的处理过程是通过读取Linuxuevent事件从而获取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中加入命令的名称,(tooboxandroid .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.cppProcessState.cpp,

  3 Binder核心框架层  IBinder(IPC传输介质)两个子类BBinderBpBinder 

                      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环境

Dalvikandroid 的虚拟机,内容在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可执行格式的字节码,javaorg目录下分别是javaorg这两个包中某些类包含的一些属性

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;

    }

转载于:https://www.cnblogs.com/retacn-yue/archive/2012/09/03/2761395.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值