Android 系统的启动过程
Android 系统的启动流程:
- RomBoot(只读存储器引导程序):这是设备上电时运行的初始软件。RomBoot执行基本的硬件初始化,确保硬件处于可以运行后续启动阶段的状态。这一阶段非常重要,因为它为整个启动过程奠定了基础。
- SPL(Secondary Program Loader):这是一种小型专用引导程序,负责加载主引导程序(如u-boot)。SPL提供比RomBoot更高级的功能,并为u-boot准备系统环境。它确保系统能够平滑过渡到下一个启动阶段。
- u-boot(通用引导加载程序):u-boot是嵌入式系统中常用的功能丰富的引导加载程序。它负责加载Linux内核,设置初始硬件环境,并提供各种引导选项和配置。u-boot确保Linux内核在正确的硬件环境中启动,并为后续的系统初始化做好准备。
- Linux内核启动:一旦u-boot加载了Linux内核,内核就会开始启动。内核启动过程中,它会挂载根文件系统,这是操作系统运行所必需的。文件系统包含了操作系统运行所需的各种程序、库和配置文件。
- 启动init程序:init程序是Android系统中的第一个用户空间进程,它负责初始化系统服务和设置运行级别。init程序会根据Android系统的初始化脚本(如init.rc)来启动和配置各种系统服务。
- 启动Zygote进程:Zygote是Android系统中的一个特殊进程,它是所有应用进程的父进程。当Zygote启动时,它会加载并初始化Android运行时环境(如Dalvik或ART虚拟机),并预加载一些常用的类和资源。这样,当后续的应用进程启动时,它们就可以共享这些已经加载的类和资源,从而提高启动速度。
- 启动SystemServer系统服务:SystemServer是Android系统中的核心服务进程,它负责启动和管理各种系统级的服务,如ActivityManagerService(负责活动管理)、PackageManagerService(负责应用包管理)等。这些服务为应用程序提供必要的系统功能和资源。
- 启动Launcher:Launcher是Android系统的桌面应用程序,它负责显示设备的主屏幕和应用程序列表。当Launcher启动时,用户就可以开始与设备进行交互了。
- 启动应用程序:在文件系统挂载、系统服务初始化以及Launcher启动之后,系统就可以开始运行用户空间的应用程序了。这些应用程序可以是预装的,也可以是用户后来安装的。
Android系统底层基于Linux Kernel, 当Kernel启动过程会创建init进程, 该进程是所有用户空间的鼻祖, init进程会启动servicemanager(binder服务管家), Zygote进程(Java进程的鼻祖). Zygote进程会创建 system_server进程以及各种app进程,下图是这几个系统重量级进程之间的层级关系。
二. init
init是Linux系统中用户空间的第一个进程(pid=1), Kerner启动后会调用/system/core/init/Init.cpp的main()方法.
2.1 Init.main
int main(int argc, char** argv) {...klog_init(); //初始化kernel logproperty_init(); //创建一块共享的内存空间,用于属性服务signal_handler_init(); //初始化子进程退出的信号处理过程property_load_boot_defaults(); //加载/default.prop文件start_property_service(); //启动属性服务器(通过socket通信)init_parse_config_file("/init.rc"); //解析init.rc文件//执行rc文件中触发器为 on early-init的语句action_for_each_trigger("early-init", action_add_queue_tail);//执行rc文件中触发器为 on init的语句action_for_each_trigger("init", action_add_queue_tail);//执行rc文件中触发器为 on late-init的语句action_for_each_trigger("late-init", action_add_queue_tail);while (true) {if (!waiting_for_exec) {execute_one_command();restart_processes();}int timeout = -1;if (process_needs_restart) {timeout = (process_needs_restart - gettime()) * 1000;if (timeout < 0)timeout = 0;}if (!action_queue_empty() || cur_action) {timeout = 0;}epoll_event ev;//循环 等待事件发生int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout));if (nr == -1) {ERROR("epoll_wait failed: %s\n", strerror(errno));} else if (nr == 1) {((void (*)()) ev.data.ptr)();}}return 0;
}
init进程的主要功能点:
- 分析和运行所有的init.rc文件;
- 生成设备驱动节点; (通过rc文件创建)
- 处理子进程的终止(signal方式);
- 提供属性服务property service。
2.2 Zygote自动重启机制
当init解析到下面这条语句,便会启动Zygote进程
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-serverclass main //伴随着main class的启动而启动socket zygote stream 660 root system //创建socketonrestart write /sys/android_power/request_state wakeonrestart write /sys/power/state ononrestart restart media //当zygote重启时,则会重启mediaonrestart restart netd // 当zygote重启时,则会重启netd
当init子进程(Zygote)退出时,会产生SIGCHLD信号,并发送给init进程,通过socket套接字传递数据,调用到wait_for_one_process()方法,根据是否是oneshot,来决定是重启子进程,还是放弃启动。由于缺省模式oneshot=false,因此Zygote一旦被杀便会再次由init进程拉起.
接下来,便是进入了Zygote进程.
三. Zygote
当Zygote进程启动后, 便会执行到frameworks/base/cmds/app_process/App_main.cpp文件的main()方法. 整个调用流程:
App_main.mainAndroidRuntime.startAndroidRuntime.startVmAndroidRuntime.startRegZygoteInit.main (首次进入Java世界)registerZygoteSocketpreloadstartSystemServerrunSelectLoop
3.1 App_main.main
int main(int argc, char* const argv[])
{AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));while (i < argc) {...//参数解析}//设置进程名if (!niceName.isEmpty()) {runtime.setArgv0(niceName.string());set_process_name(niceName.string());}if (zygote) {// 启动AppRuntime,见小节[3.2]runtime.start("com.android.internal.os.ZygoteInit", args, zygote);} else if (className) {runtime.start("com.android.internal.os.RuntimeInit", args, zygote);}
}
在app_process进程启动过程,有两个分支:
- 当zygote为true时,则执行ZygoteInit.main()
- 当zygote为false时,则执行RuntimeInit.main()
3.2 AndroidRuntime::start
[-> AndroidRuntime.cpp]
void AndroidRuntime::start(const char* className, const Vector<String8>& options)
{...// 虚拟机创建if (startVm(&mJavaVM, &env, zygote) != 0) {return;}onVmCreated(env);// JNI方法注册if (startReg(env) < 0) {return;}...// 调用ZygoteInit.main()方法[见小节3.3]env->CallStaticVoidMethod(startClass, startMeth, strArray);
3.3 ZygoteInit.main
[–>ZygoteInit.java]
public static void main(String argv[]) {try {...registerZygoteSocket(socketName); //为Zygote注册socketpreload(); // 预加载类和资源[见小节3.4]...if (startSystemServer) {startSystemServer(abiList, socketName);//启动system_server[见小节3.5]}Log.i(TAG, "Accepting command socket connections");runSelectLoop(abiList); //进入循环模式[见小节3.6]...} catch (MethodAndArgsCaller caller) {caller.run(); //启动system_server中会讲到。}...
}
3.4 ZygoteInit.preload
[–>ZygoteInit.java]
static void preload() {Log.d(TAG, "begin preload");preloadClasses();preloadResources();preloadOpenGL();preloadSharedLibraries();WebViewFactory.prepareWebViewInZygote();Log.d(TAG, "end preload");
}
3.5 ZygoteInit.startSystemServer
[–>ZygoteInit.java]
private static boolean startSystemServer(String abiList, String socketName)throws MethodAndArgsCaller, RuntimeException {...// fork子进程system_serverpid = Zygote.forkSystemServer(parsedArgs.uid, parsedArgs.gid,parsedArgs.gids,parsedArgs.debugFlags,null,parsedArgs.permittedCapabilities,parsedArgs.effectiveCapabilities);...if (pid == 0) {if (hasSecondZygote(abiList)) {waitForSecondaryZygote(socketName);}//进入system_server进程[见小节4.1]handleSystemServerProcess(parsedArgs);}return true;
}
3.6 ZygoteInit.runSelectLoop
[–>ZygoteInit.java]
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();//sServerSocket是socket通信中的服务端,即zygote进程fds.add(sServerSocket.getFileDescriptor());peers.add(null);while (true) {StructPollfd[] pollFds = new StructPollfd[fds.size()];for (int i = 0; i < pollFds.length; ++i) {pollFds[i] = new StructPollfd();pollFds[i].fd = fds.get(i);pollFds[i].events = (short) POLLIN;}...Os.poll(pollFds, -1);for (int i = pollFds.length - 1; i >= 0; --i) {//采用I/O多路复用机制,当客户端发出 连接请求或者数据处理请求时,则执行continueif ((pollFds[i].revents & POLLIN) == 0) {continue;}if (i == 0) {//创建客户端连接ZygoteConnection newPeer = acceptCommandPeer(abiList);peers.add(newPeer);fds.add(newPeer.getFileDesciptor());} else {//处理客户端数据事务boolean done = peers.get(i).runOnce();if (done) {peers.remove(i);fds.remove(i);}}}}
}
Zygote进程创建Java虚拟机,并注册JNI方法, 真正成为Java进程的母体,用于孵化Java进程. 在创建完system_server进程后,zygote功成身退,调用runSelectLoop(),随时待命,当接收到请求创建新进程请求时立即唤醒并执行相应工作。
四. system_server
Zygote通过fork后创建system_server进程,在小节[3.5]执行完startSystemServer()方法后,进入到了handleSystemServerProcess()方法,如下所示。
4.1 handleSystemServerProcess
[–>ZygoteInit.java]
private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller {...if (parsedArgs.niceName != null) {//设置当前进程名为"system_server"Process.setArgV0(parsedArgs.niceName);}final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");if (systemServerClasspath != null) {//执行dex优化操作,比如services.jarperformSystemServerDexOpt(systemServerClasspath);}if (parsedArgs.invokeWith != null) {...} else {ClassLoader cl = null;if (systemServerClasspath != null) {cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());Thread.currentThread().setContextClassLoader(cl);}//[见小节4.2]RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);}
}
system_server进程创建PathClassLoader类加载器.
4.2 RuntimeInit.zygoteInit
[–> RuntimeInit.java]
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");redirectLogStreams(); //重定向log输出commonInit(); // 通用的一些初始化nativeZygoteInit(); // zygote初始化applicationInit(targetSdkVersion, argv, classLoader); // [见小节3.4]
}
Binder线程池启动
nativeZygoteInit()方法经过层层调用,会进入app_main.cpp中的onZygoteInit()方法, Binder线程池的创建也是在这个过程,如下:
virtual void onZygoteInit() {sp<ProcessState> proc = ProcessState::self();proc->startThreadPool(); //启动新binder线程池
}
捕获特殊异常
applicationInit()方法经过层层调用,会抛出异常ZygoteInit.MethodAndArgsCaller(m, argv), 具体过程如下:
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,ClassLoader classLoader) {...VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);final Arguments args = new Arguments(argv);//找到目标类的静态main()方法invokeStaticMain(args.startClass, args.startArgs, classLoader);
}private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)throws ZygoteInit.MethodAndArgsCaller {//此处的className等于SystemServerClass<?> cl = Class.forName(className, true, classLoader);Method m = cl.getMethod("main", new Class[] { String[].class });//抛出异常Runnable对象throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
设置虚拟机的堆利用率0.75和置TargetSdk版本;并抛出异常,然后由ZygoteInit.main()捕获该异常, 见下文
4.3 ZygoteInit.main
[–>ZygoteInit.java]
public static void main(String argv[]) {try {startSystemServer(abiList, socketName); //抛出MethodAndArgsCaller异常....} catch (MethodAndArgsCaller caller) {caller.run(); //此处通过反射,会调用SystemServer.main()方法 [见小节4.4]} catch (RuntimeException ex) {...}
}static class MethodAndArgsCaller implements Runnable {private final Method mMethod;private final String[] mArgs;public MethodAndArgsCaller(Method method, String[] args) {mMethod = method;mArgs = args;}public void run() {//执行SystemServer.main()mMethod.invoke(null, new Object[] { mArgs });}
}
采用抛出异常的方式,用于栈帧清空,提供利用率, 以至于现在大家看到的每个Java进程的调用栈如下:
...at com.android.server.SystemServer.main(SystemServer.java:175)at java.lang.reflect.Method.invoke!(Native method)at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
4.4 SystemServer.main
[–>SystemServer.java]
public final class SystemServer {...public static void main(String[] args) {//先初始化SystemServer对象,再调用对象的run()方法new SystemServer().run();}
}
4.5 SystemServer.run
[–>SystemServer.java]
private void run() {if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {Slog.w(TAG, "System clock is before 1970; setting to 1970.");SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);}...Slog.i(TAG, "Entered the Android system server!");EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());Looper.prepareMainLooper();// 准备主线程looper//加载android_servers.so库,该库包含的源码在frameworks/base/services/目录下System.loadLibrary("android_servers");//检测上次关机过程是否失败,该方法可能不会返回performPendingShutdown();createSystemContext(); //初始化系统上下文//创建系统服务管理mSystemServiceManager = new SystemServiceManager(mSystemContext);LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);//启动各种系统服务try {startBootstrapServices(); // 启动引导服务startCoreServices(); // 启动核心服务startOtherServices(); // 启动其他服务[见小节4.6]} catch (Throwable ex) {Slog.e("System", "************ Failure starting system services", ex);throw ex;}//一直循环执行Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");
}
4.6 服务启动
public final class SystemServer {private void startBootstrapServices() {...//phase100mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);...}private void startOtherServices() {...//phase480 和phase500mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);...//[见小节4.7]mActivityManagerService.systemReady(new Runnable() {@Overridepublic void run() {//phase550mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);...//phase600mSystemServiceManager.startBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);}}}
}
- start: 创建AMS, PMS, LightsService, DMS.
- phase100: 进入Phase100, 创建PKMS, WMS, IMS, DBMS, LockSettingsService, JobSchedulerService, MmsService等服务;
- phase480 && 500: 进入Phase480, 调用WMS, PMS, PKMS, DisplayManagerService这4个服务的systemReady();
- Phase550: 进入phase550, 执行AMS.systemReady(), 启动SystemUI, WebViewFactory, Watchdog.
- Phase600: 进入phase600, 执行AMS.systemReady(), 执行各种服务的systemRunning().
- Phase1000: 进入1000, 执行finishBooting, 启动启动on-hold进程.
4.7 AMS.systemReady
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {public void systemReady(final Runnable goingCallback) {... //update相关mSystemReady = true;//杀掉所有非persistent进程removeProcessLocked(proc, true, false, "system update done");mProcessesReady = true;goingCallback.run(); //[见小节1.6.2]addAppLocked(info, false, null); //启动所有的persistent进程mBooting = true;//启动homestartHomeActivityLocked(mCurrentUserId, "systemReady");//恢复栈顶的ActivitymStackSupervisor.resumeTopActivitiesLocked();}
}
System_server主线程的启动工作,总算完成, 进入Looper.loop()状态,等待其他线程通过handler发送消息再处理.
五. app
对于普通的app进程,跟system_server进程的启动过来有些类似.不同的是app进程是向发消息给system_server进程, 由system_server向zygote发出创建进程的请求.进程创建后 接下来会进入ActivityThread.main()过程。
5.1 ActivityThread.main
public static void main(String[] args) {...Environment.initForCurrentUser();...Process.setArgV0("<pre-initialized>");//创建主线程looperLooper.prepareMainLooper();ActivityThread thread = new ActivityThread();thread.attach(false); //attach到系统进程if (sMainThreadHandler == null) {sMainThreadHandler = thread.getHandler();}//主线程进入循环状态Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");
}
5.2 调用栈对比
App进程的主线程调用栈的栈底如下:
...at android.app.ActivityThread.main(ActivityThread.java:5442)at java.lang.reflect.Method.invoke!(Native method)at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
跟前面介绍的system_server进程调用栈对比:
at com.android.server.SystemServer.main(SystemServer.java:175)at java.lang.reflect.Method.invoke!(Native method)at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
六. 启动日志分析
以下列举启动部分重要进程以及关键节点会打印出的log
/system/bin/vold: 383
/system/bin/lmkd: 432
/system/bin/surfaceflinger: 434
/system/bin/debuggerd64: 537
/system/bin/mediaserver: 540
/system/bin/installd: 541
/system/vendor/bin/thermal-engine: 552zygote64: 557
zygote: 558
system_server: 1274
1. before zygote日志
//启动vold, 再列举当前系统所支持的文件系统. 执行到system/vold/main.cpp的main()
11-23 14:36:47.474 383 383 I vold : Vold 3.0 (the awakening) firing up
11-23 14:36:47.475 383 383 V vold : Detected support for: ext4 vfat
//使用内核的lmk策略
11-23 14:36:47.927 432 432 I lowmemorykiller: Using in-kernel low memory killer interface
//启动SurfaceFlinger
11-23 14:36:48.041 434 434 I SurfaceFlinger: SurfaceFlinger is starting
11-23 14:36:48.042 434 434 I SurfaceFlinger: SurfaceFlinger's main thread ready to run. Initializing graphics H/W...
// 开机动画
11-23 14:36:48.583 508 508 I BootAnimation: bootanimation launching ...
// debuggerd
11-23 14:36:50.306 537 537 I : debuggerd: starting
// installd启动
11-23 14:36:50.311 541 541 I installd: installd firing up
// thermal守护进程
11-23 14:36:50.369 552 552 I ThermalEngine: Thermal daemon started
2. zygote日志
// Zygote64进程(Zygote): AndroidRuntime::start
11-23 14:36:51.260 557 557 D AndroidRuntime: >>>>>> START com.android.internal.os.ZygoteInit uid 0 <<<<<<
// Zygote64进程: AndroidRuntime::startVm
11-23 14:36:51.304 557 557 D AndroidRuntime: CheckJNI is OFF// 执行ZygoteInit.preload()
11-23 14:36:52.134 557 557 D Zygote : begin preload
// 执行ZygoteInit.preloadClasses(), 预加载3860个classes, 花费时长746ms
11-23 14:36:52.134 557 557 I Zygote : Preloading classes...
11-23 14:36:52.881 557 557 I Zygote : ...preloaded 3860 classes in 746ms.// 执行ZygoteInit.preloadClasses(), 预加载86组资源, 花费时长179ms
11-23 14:36:53.114 557 557 I Zygote : Preloading resources...
11-23 14:36:53.293 557 557 I Zygote : ...preloaded 86 resources in 179ms.// 执行ZygoteInit.preloadSharedLibraries()
11-23 14:36:53.494 557 557 I Zygote : Preloading shared libraries...
11-23 14:36:53.503 557 557 D Zygote : end preload// 执行com_android_internal_os_Zygote_nativeForkSystemServer(),成功fork出system_server进程
11-23 14:36:53.544 557 557 I Zygote : System server process 1274 has been created
// Zygote开始进入runSelectLoop()
11-23 14:36:53.546 557 557 I Zygote : Accepting command socket connections
3. system_server日志
//进入system_server, 建立跟Zygote进程的socket通道
11-23 14:36:53.586 1274 1274 I Zygote : Process: zygote socket opened, supported ABIS: armeabi-v7a,armeabi
// 执行SystemServer.run()
11-23 14:36:53.618 1274 1274 I SystemServer: Entered the Android system server! <===> boot_progress_system_run
// 等待installd准备就绪
11-23 14:36:53.707 1274 1274 I Installer: Waiting for installd to be ready.//服务启动
11-23 14:36:53.732 1274 1274 I ActivityManager: Memory class: 192//phase100
11-23 14:36:53.883 1274 1274 I SystemServiceManager: Starting phase 100
11-23 14:36:53.902 1274 1274 I SystemServer: Package Manager
11-23 14:37:03.816 1274 1274 I SystemServer: User Service
...
11-23 14:37:03.940 1274 1274 I SystemServer: Init Watchdog
11-23 14:37:03.941 1274 1274 I SystemServer: Input Manager
11-23 14:37:03.946 1274 1274 I SystemServer: Window Manager
...
11-23 14:37:04.081 1274 1274 I SystemServiceManager: Starting com.android.server.MountService$Lifecycle
11-23 14:37:04.088 1274 2717 D MountService: Thinking about reset, mSystemReady=false, mDaemonConnected=true
11-23 14:37:04.088 1274 1274 I SystemServiceManager: Starting com.android.server.UiModeManagerService
11-23 14:37:04.520 1274 1274 I SystemServer: NetworkTimeUpdateService//phase480 && 500
11-23 14:37:05.056 1274 1274 I SystemServiceManager: Starting phase 480
11-23 14:37:05.061 1274 1274 I SystemServiceManager: Starting phase 500
11-23 14:37:05.231 1274 1274 I ActivityManager: System now ready <==> boot_progress_ams_ready
11-23 14:37:05.234 1274 1274 I SystemServer: Making services ready
11-23 14:37:05.243 1274 1274 I SystemServer: WebViewFactory preparation//phase550
11-23 14:37:05.234 1274 1274 I SystemServiceManager: Starting phase 550
11-23 14:37:05.237 1274 1288 I ActivityManager: Force stopping com.android.providers.media appid=10010 user=-1: vold reset//Phase600
11-23 14:37:06.066 1274 1274 I SystemServiceManager: Starting phase 600
11-23 14:37:06.236 1274 1274 D MountService: onStartUser 0
4. logcat小技巧
通过adb bugreport抓取log信息.先看zygote是否起来, 再看system_server主线程的运行情况,再看ActivityManager情况
adb logcat -s Zygote
adb logcat -s SystemServer
adb logcat -s SystemServiceManager
adb logcat | grep "1359 1359" //system_server情况
adb logcat -s ActivityManager
现场调试命令
- cat proc/[pid]/stack ==> 查看kernel调用栈
- debuggerd -b [pid] ==> 也不可以不带参数-b, 则直接输出到/data/tombstones/目录
- kill -3 [pid] ==> 生成/data/anr/traces.txt文件
- lsof [pid] ==> 查看进程所打开的文件
七. 总结
各大核心进程启动后,都会进入各种对象所相应的main()方法,如下
进程main方法
进程 | 主方法 |
---|---|
init进程 | Init.main() |
zygote进程 | ZygoteInit.main() |
app_process进程 | RuntimeInit.main() |
system_server进程 | SystemServer.main() |
app进程 | ActivityThread.main() |
注意app_process进程是指通过/system/bin/app_process启动的进程,且后面跟的参数不带–zygote,即并非启动zygote进程。 比如常见的有通过adb shell方式来执行am,pm等命令,便是这种方式。
重启相关进程
关于重要进程重启的过程,会触发哪些关联进程重启名单:
- zygote:触发media、netd以及子进程(包括system_server进程)重启;
- system_server: 触发zygote重启;
- surfaceflinger:触发zygote重启;
- servicemanager: 触发zygote、healthd、media、surfaceflinger、drm重启
所以,surfaceflinger,servicemanager,zygote自身以及system_server进程被杀都会触发Zygote重启。
相关文章:

Android 系统的启动过程
Android 系统的启动流程: RomBoot(只读存储器引导程序):这是设备上电时运行的初始软件。RomBoot执行基本的硬件初始化,确保硬件处于可以运行后续启动阶段的状态。这一阶段非常重要,因为它为整个启动过程奠定…...

jenkins配置源码管理的git地址时,怎么使用不了 credential凭证信息
前提 Jenkins使用docker部署 问题 (在jenlins中设置凭证的方式)在Jenkins的任务重配置Git地址,并且设置了git凭证,但是验证不通过,报错; 无法连接仓库:Command "git ls-remote -h -- http://192.1XX.0.98:X02/…...

Emotion Prompt-LLM能够理解并能通过情感刺激得以增强
Large Language Models Understand and Can be Enhanced by Emotional Stimuli 情感智能对我们的日常行为和互动产生了显著的影响。尽管大型语言模型(LLMs)被视为向人工通用智能迈进的一大步,在许多任务中表现出色,但目前尚不清楚…...

流畅的 Python 第二版(GPT 重译)(十三)
第二十四章:类元编程 每个人都知道调试比一开始编写程序要困难两倍。所以如果你在编写时尽可能聪明,那么你将如何调试呢? Brian W. Kernighan 和 P. J. Plauger,《编程风格的要素》 类元编程是在运行时创建或自定义类的艺术。在 P…...

C/C++炸弹人游戏
参考书籍《啊哈,算法》,很有意思的一本算法书,小白也可以看懂,详细见书,这里只提供代码和运行结果。 这里用到的是枚举思想,还有更好地搜索做法。 如果大家有看不懂的地方或提出建议,欢迎评论区…...

③【Docker】Docker部署Nginx
个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ ③【Docker】Docker部署Nginx docker拉取nginx…...

Elasticsearch:使用 OpenAI、LangChain 和 Streamlit 的基于 LLM 的 PDF 摘要器和 Q/A 应用程序
嘿! 您是否曾经感觉自己被淹没在信息的海洋中? 有这么多的书要读,而时间却这么少,很容易就会超负荷,对吧? 但猜猜怎么了? 你可以使用大型语言模型创建自定义聊天机器人,该模型可以帮…...

Linux课程____进程管理
记录工作日志 script 240319.log CTRLd 退出 cat 240319.log //查看 一、查看进程 1.静态 ps -aux 显示所有包含其他使用者的行程 ps -elf 2.动态 top 3.pgrep 查看特定条件的进程 pgrep -l “log” 搜索特定的程序 pgrep -l "ssh" pgrep -l -U…...

算法设计与分析-动态规划算法的应用——沐雨先生
一、实验目的 1. 掌握动态规划算法的基本思想,包括最优子结构性质和基于表格的最优值计算方法。 2.熟练掌握分阶段的和递推的最优子结构分析方法。 3. 学会利用动态规划算法解决实际问题 。 二、实验内容 1. 问题描述 &#…...

Flutter-仿淘宝京东录音识别图标效果
效果 需求 弹起键盘,录制按钮紧挨着输入框收起键盘,录制按钮回到初始位置 实现 第一步:监听键盘弹起并获取键盘高度第二步:根据键盘高度,录制按钮高度计算偏移高度,并动画移动第三步:键盘收起…...

雷池 WAF 社区版:下一代 Web 应用防火墙的革新
黑客的挑战 智能语义分析算法: 黑客们常利用复杂技术进行攻击,但雷池社区版的智能语义分析算法能深入解析攻击本质,即使是最复杂的攻击手法也难以逃脱。 0day攻击防御: 传统防火墙难以防御未知攻击,但雷池社区版能有效…...
音视频实战---音视频解码
该方法只能解码裸流。 1、使用avcodec_find_decoder查找解码器 根据使用解码器类型,决定是解码音频还是解码视频。 2、 使用av_parser_init获取裸流解析器和方法 3、使用avcodec_alloc_context3分配编解码器上下文 4、使用avcodec_open2将解码器和解码器上下文…...

MyBatisPlus 之四:MP 的乐观锁和逻辑删除、分组、排序、链式的实现步骤
乐观锁 乐观锁是相对悲观锁而言的,乐观锁假设数据一般情况不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果冲突,则返回给用户异常信息,让用户决定如何去做。 乐观锁适用…...

node.js常用的命令
Node.js 是一个用于执行 JavaScript 代码的运行时环境。以下命令是 Node.js 开发中常用的命令,可以帮助你进行包管理、项目配置和代码执行等操作。 node -v:检查 Node.js 的版本。npm -v:检查 npm(Node.js 包管理器)的…...
Python从入门到精通秘籍十
一、Python之了解异常 当在Python中执行代码时,如果发生错误,就会抛出异常(Exception)。处理异常是编写健壮的代码的重要部分。Python提供了try-except语句来捕获和处理异常。 下面是使用Python代码详细讲解异常处理的例子&…...

Android:adb命令
执行adb命令的窗口如下 Mac或Linux系统里的终端窗口; window系统运行输入cmd打开的指令窗口; Android Studio 里控制下面的Terminal窗口 1. 查看已链接的设备和模拟器 adb devices -l 2. 查看Android内核版本号 adb shell getprop ro.build.version.re…...
Github基本功能和使用技巧
基础功能 创建仓库(Repository):在GitHub上创建一个新的仓库,可以通过点击页面右上角的“New”按钮开始。选择仓库的名称、描述和许可证等信息,并选择是否将仓库设置为公开或私有。 克隆仓库(Clone&#x…...
mac上系统偏好里无法停止mysql
使用强制杀死进程: sudo kill -9 pid原文:https://www.cnblogs.com/yalong/p/14136997.html 命令行也没有关闭成功:https://blog.51cto.com/u_5018054/5101645...

launchctl及其配置、使用、示例
文章目录 launchctl 是什么Unix / Linux类似的工具有什么哪个更常用配置使用常用子命令示例加载一个 launch agent:卸载一个 launch daemon:列出所有已加载的服务:启动一个服务:停止一个服务:禁用一个服务:启用一个服务: 附com.example.myagent.plist内容有趣的例子参考 launch…...

如何在Ubuntu系统搭建Excalidraw容器并实现公网访问本地绘制流程图
文章目录 1. 安装Docker2. 使用Docker拉取Excalidraw镜像3. 创建并启动Excalidraw容器4. 本地连接测试5. 公网远程访问本地Excalidraw5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定公网地址远程访问 本文主要介绍如何在Ubuntu系统使用Docker部署开源白板工具Excal…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...