init 进程是Android系统的第一个进程,很多重要职责,例如创建Zygote和属性服务等。 init位于路劲system、core/init.
1.启动电源以及系统启动
2.引导程序Bootloader
3.linux内核启动
4.init进程启动
在main函数中system/core/init/init.cpp
int main(int argc, char** argv) {
…
//对属性服务进行初始化
property_init(); //1
…
//用于设置子进程信号处理函数,如果子进程(zogete进程)异常退出,init进程会调用该函数中设定的信号处理函数来处理
signal_handler_init();//2
…
//启动属性服务
start_property-service();//3
…
//解析init.rc配置文件
parser.ParseConfig(“init.rc”);//4
…
//重启死去的进程
restart_processes();//5
}
注释2是为了防止僵尸进程
父进程不知道子进程终止,但是此时系统进程表中还为它保留了一定的信息,子进程为僵尸进程。 进程表资源有限。
init.rc是一个配置文件,内部由Android初始化语言编写(Android Init Language)编写的脚本,它主要包含五种类型语句:
Action、Commands、Services、Options和Import。init.rc的配置代码如下所示。
system/core/rootdir/init.rc
on init
sysclktz 0
# Mix device-specific information into the entropy pool
copy /proc/cmdline /dev/urandom
copy /default.prop /dev/urandom
...
on boot
# basic network init
ifup lo
hostname localhost
domainname localdomain
# set RLIMIT_NICE to allow priorities from 19 to -20
setrlimit 13 40 40
...
init.rc中的Action星语句是ActionParser来进行解析,而Service由ServiceParser来进行解析。解析service,会用到两个函数,一个是ParseSection,它会解析service的rc文件,比如上文讲到的init.zygote64.rc,ParseSection函数主要用来搭建service的架子。另一个是ParseLineSection,用于解析子项。
Start方法
bool Service::Start() {
...
pid_t pid = fork();//1.fork函数创建子进程
if (pid == 0) {//2运行在子进程中
umask(077);
...
//3.通过execve执行程序
if (execve(args_[0].c_str(), (char**) &strs[0], (char**) ENV) < 0) {
ERROR("cannot execve('%s'): %s\n", args_[0].c_str(), strerror(errno));
}
_exit(127);
}
走到1处,子进程还没被启动。frok创建子进程,pid=0 说明在子线程中运行。3处service子进程就会被启动,进入到service的main函数中。
frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
...
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);//1
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
return 10;
}
}
1处的代码可以得知调用runtime(AppRuntime)的start来启动zygote。
ystem/core/init/property_service.cpp
void property_init() {
if (__system_property_area_init()) {
ERROR("Failed to initialize property area\n");
exit(1);
}
}
void start_property_service() {
property_set_fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
0666, 0, 0, NULL);//1
if (property_set_fd == -1) {
ERROR("start_property_service socket creation failed: %s\n", strerror(errno));
exit(1);
}
listen(property_set_fd, 8);//2
register_epoll_handler(property_set_fd, handle_property_set_fd);//3
}
注释1处用来创建非阻塞的socket。注释2处调用listen函数对property_set_fd进行监听,这样创建的socket就成为了server,也就是属性服务;listen函数的第二个参数设置8意味着属性服务最多可以同时为8个试图设置属性的用户提供服务。注释3处的代码将property_set_fd放入了epoll句柄中,用epoll来监听property_set_fd:当property_set_fd中有数据到来时,init进程将用handle_property_set_fd函数进行处理。
在linux新的内核中,epoll用来替换select,epoll最大的好处在于它不会随着监听fd数目的增长而降低效率。因为内核中的select实现是采用轮询来处理的,轮询的fd数目越多,自然耗时越多。
会调用handle_property_set_fd函数进行处理:
system/core/init/property_service.cpp
static void handle_property_set_fd()
{
...
handler_property_set(socket,prop_value,pro_value,true);//1
}
8.0在7.0做了进一步的判断,普通属性和控制属性。
init进程主要做了三件事:
1.创建和挂载启动所需的文件目录
2.初始化和启动属性服务
3.解析init.rc配置文件并启动zygote进程、
在Android系统中,DVM(Dalvik虚拟机)和ART、应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程来创建的,我们也将它称为孵化器。它通过fork
(复制进程)的形式来创建应用程序进程和SystemServer进程,由于Zygote进程在启动时会创建DVM或者ART,因此通过fork而创建的应用程序进程和SystemServer进程可以在内部获取一个DVM的实例拷贝。
启动流程
Zygote进程共做了如下几件事:
1.创建AppRuntime并调用其start方法,启动Zygote进程。
2.创建DVM并为DVM注册JNI.
3.通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。
4.通过registerZygoteSocket函数创建服务端Socket,并通过runSelectLoop函数等待ActivityManagerService的请求来创建新的应用程序进程。
5.启动SystemServer进程。
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
// 关闭 zygote进程创建的socket 该进程对systemserver没用
zygoteServer.closeServerSocket();
handleSystemServerProcess(parsedArgs);
handleSystemServerProcess函数的代码:
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = createSystemServerClassLoader(systemServerClasspath,
parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);//2
2处调用RuntimeInit的zygoteInit函数
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
nativeZygoteInit();//1启动binder线程池
applicationInit(targetSdkVersion, argv, classLoader);//2进入systemServer的main方法
invokeStaticMain
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
...
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
通过反射返回的cl为SystemServer类。找到SystemServer中的main函数。将找到的main函数传入到MethodAndArgsCaller异常中并抛出该异常。截获MethodAndArgsCaller异常的代码在ZygoteInit.java的main函数中
rameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
...
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();//1
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
在注释1处调用了MethodAndArgsCaller的run函数:
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
...
}
}
}
SystemServer的main函数:
frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
main函数中只调用了SystemServer的run函数,如下所示。
private void run() {
...
System.loadLibrary("android_servers");//1
...
mSystemServiceManager = new SystemServiceManager(mSystemContext);//2
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
...
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
startBootstrapServices();//3
startCoreServices();//4
startOtherServices();//5
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
...
}
SyetemServer在启动时做了如下工作:
1.启动Binder线程池,这样就可以与其他进程进行通信。
2.创建SystemServiceManager用于对系统的服务进行创建、启动和生命周期管理。
3.启动各种系统服务。
launcher通俗的就是Android的系统的桌面。作用:
1、作为Android系统的启动器,用于启动应用程序
2、作为系统的桌面,用于显示和管理应用程序的快捷图标或者其他桌面组件
在systemServer 中startOtherServices函数,会调用ActivityManagerService的systemReady函数。
systemReady函数中调用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked函数:
Launcher的onCreate函数如下所示。
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
@Override
protected void onCreate(Bundle savedInstanceState) {
...
LauncherAppState app = LauncherAppState.getInstance();//1 获取实例
mDeviceProfile = getResources().getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE ?
app.getInvariantDeviceProfile().landscapeProfile
: app.getInvariantDeviceProfile().portraitProfile;
mSharedPrefs = Utilities.getPrefs(this);
mIsSafeModeEnabled = getPackageManager().isSafeMode();
mModel = app.setLauncher(this);//2
....
if (!mRestoring) {
if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {
mModel.startLoader(PagedView.INVALID_RESTORE_PAGE);//3
} else {
mModel.startLoader(mWorkspace.getRestorePage());
}
}
...
}
setluncher 处会调用LauncherModel的initialize函数:
在initialize函数中会将Callbacks,也就是传入的Launcher 封装成一个弱引用对象。因此我们得知mCallbacks变量指的就是封装成弱引用对象的Launcher,这个mCallbacks后文会用到它。
再回到Launcher的onCreate函数,在注释2处调用了LauncherModel的startLoader函数…
1.启动电源以及系统启动
当电源按下时引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序Bootloader到RAM,然后执行。
2.引导程序BootLoader
引导程序BootLoader是在Android操作系统开始运行前的一个小程序,它的主要作用是把系统OS拉起来并运行。
3.Linux内核启动
内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。当内核完成系统设置,它首先在系统文件中寻找init.rc文件,并启动init进程。
4.init进程启动
初始化和启动属性服务,并且启动Zygote进程。
5.Zygote进程启动
创建JavaVM并为JavaVM注册JNI,创建服务端Socket,启动SystemServer进程。
6.SystemServer进程启动
启动Binder线程池和SystemServiceManager,并且启动各种系统服务。
7.Launcher启动
被SystemServer进程启动的ActivityManagerService会启动Launcher,Launcher启动后会将已安装应用的快捷图标显示到界面上。