App启动流程
目录介绍
- 1.什么是Zygote进程
- 1.1 简单介绍
- 1.2 各个进程的先后顺序
- 1.3 进程作用说明
- 2.Zygote进程的启动流程
- 2.1 源码位置
- 2.2 ZygoteInit类的main方法
- 2.3 registerZygoteSocket(socketName)分析
- 2.4 preLoad()方法分析
- 2.5 startSystemServer()启动进程
- 3.SystemServer进程启动流程
- 3.1 SystemServer进程简介
- 3.2 SystemServer的main方法
- 3.3 查看run方法
- 3.4 run方法中createSystemContext()解析
- 3.5 mSystemServiceManager的创建
- 4.启动服务
- 4.1 启动哪些服务
- 4.2 启动服务流程源码分析
- 4.3 启动部分服务
好消息
- 博客笔记大汇总【16年3月到至今】,包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期更新维护并且修正,持续完善……开源的文件是markdown格式的!同时也开源了生活博客,从12年起,积累共计47篇[近20万字],转载请注明出处,谢谢!
- 链接地址:https://github.com/yangchong211/YCBlogs
- 如果觉得好,可以star一下,谢谢!当然也欢迎提出建议,万事起于忽微,量变引起质变!
1.什么是Zygote进程
1.1 简单介绍
- Zygote进程是所有的android进程的父进程,包括SystemServer和各种应用进程都是通过Zygote进程fork出来的。Zygote(孵化)进程相当于是android系统的根进程,后面所有的进程都是通过这个进程fork出来的
- 虽然Zygote进程相当于Android系统的根进程,但是事实上它也是由Linux系统的init进程启动的。
1.2 各个进程的先后顺序
- init进程 --> Zygote进程 --> SystemServer进程 -->各种应用进程
1.3 进程作用说明
- init进程:linux的根进程,android系统是基于linux系统的,因此可以算作是整个android操作系统的第一个进程;
- Zygote进程:android系统的根进程,主要作用:可以作用Zygote进程fork出SystemServer进程和各种应用进程;
- SystemService进程:主要是在这个进程中启动系统的各项服务,比如ActivityManagerService,PackageManagerService,WindowManagerService服务等等;
- 各种应用进程:启动自己编写的客户端应用时,一般都是重新启动一个应用进程,有自己的虚拟机与运行环境;
2.Zygote进程的启动流程
2.1 源码位置
- 位置:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
- Zygote进程mian方法主要执行逻辑:
- 初始化DDMS;
- 注册Zygote进程的socket通讯;
- 初始化Zygote中的各种类,资源文件,OpenGL,类库,Text资源等等;
- 初始化完成之后fork出SystemServer进程;
- fork出SystemServer进程之后,关闭socket连接;
2.2 ZygoteInit类的main方法
- init进程在启动Zygote进程时一般都会调用ZygoteInit类的main方法,因此这里看一下该方法的具体实现(基于android23源码);
- 调用enableDdms(),设置DDMS可用,可以发现DDMS启动的时机还是比较早的,在整个Zygote进程刚刚开始要启动额时候就设置可用。
- 之后初始化各种参数
- 通过调用registerZygoteSocket方法,注册为Zygote进程注册Socket
- 然后调用preload方法实现预加载各种资源
- 然后通过调用startSystemServer开启SystemServer服务,这个是重点
public static void main(String argv[]) {
try {
//设置ddms可以用
RuntimeInit.enableDdms();
SamplingProfilerIntegration.start();
boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
} if (abiList == null) {
throw new RuntimeException("No ABI list supplied.");
} registerZygoteSocket(socketName);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
SamplingProfilerIntegration.writeZygoteSnapshot(); gcAndFinalize();
Trace.setTracingEnabled(false); if (startSystemServer) {
startSystemServer(abiList, socketName);
} Log.i(TAG, "Accepting command socket connections");
runSelectLoop(abiList); closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
2.3 registerZygoteSocket(socketName)分析
- 调用registerZygoteSocket(String socketName)为Zygote进程注册socket
private static void registerZygoteSocket(String socketName) {
if (sServerSocket == null) {
int fileDesc;
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(fullSocketName + " unset or invalid", ex);
} try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
sServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
2.4 preLoad()方法分析
- 源码如下所示
static void preload() {
Log.d(TAG, "begin preload");
preloadClasses();
preloadResources();
preloadOpenGL();
preloadSharedLibraries();
preloadTextResources();
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
WebViewFactory.prepareWebViewInZygote();
Log.d(TAG, "end preload");
}
- 大概操作是这样的:
- preloadClasses()用于初始化Zygote中需要的class类;
- preloadResources()用于初始化系统资源;
- preloadOpenGL()用于初始化OpenGL;
- preloadSharedLibraries()用于初始化系统libraries;
- preloadTextResources()用于初始化文字资源;
- prepareWebViewInZygote()用于初始化webview;
2.5 startSystemServer()启动进程
- 这段逻辑的执行逻辑就是通过Zygote fork出SystemServer进程
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_BLOCK_SUSPEND,
OsConstants.CAP_KILL,
OsConstants.CAP_NET_ADMIN,
OsConstants.CAP_NET_BIND_SERVICE,
OsConstants.CAP_NET_BROADCAST,
OsConstants.CAP_NET_RAW,
OsConstants.CAP_SYS_MODULE,
OsConstants.CAP_SYS_NICE,
OsConstants.CAP_SYS_RESOURCE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG
);
/* 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,1021,1032,3001,3002,3003,3006,3007",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null; int pid; try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); /* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
} /* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
} handleSystemServerProcess(parsedArgs);
} return true;
}
3.SystemServer进程启动流程
3.1 SystemServer进程简介
- SystemServer进程主要的作用是在这个进程中启动各种系统服务,比如ActivityManagerService,PackageManagerService,WindowManagerService服务,以及各种系统性的服务其实都是在SystemServer进程中启动的,而当我们的应用需要使用各种系统服务的时候其实也是通过与SystemServer进程通讯获取各种服务对象的句柄的。
3.2 SystemServer的main方法
- 如下所示,比较简单,只是new出一个SystemServer对象并执行其run方法,查看SystemServer类的定义我们知道其实final类型的,所以我们一般不能重写或者继承。

3.3 查看run方法
- 代码如下所示
- 首先判断系统当前时间,若当前时间小于1970年1月1日,则一些初始化操作可能会处所,所以当系统的当前时间小于1970年1月1日的时候,设置系统当前时间为该时间点。
- 然后是设置系统的语言环境等
- 接着设置虚拟机运行内存,加载运行库,设置SystemServer的异步消息
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);
} if (!SystemProperties.get("persist.sys.language").isEmpty()) {
final String languageTag = Locale.getDefault().toLanguageTag(); SystemProperties.set("persist.sys.locale", languageTag);
SystemProperties.set("persist.sys.language", "");
SystemProperties.set("persist.sys.country", "");
SystemProperties.set("persist.sys.localevar", "");
} Slog.i(TAG, "Entered the Android system server!");
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis()); SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary()); if (SamplingProfilerIntegration.isEnabled()) {
SamplingProfilerIntegration.start();
mProfilerSnapshotTimer = new Timer();
mProfilerSnapshotTimer.schedule(new TimerTask() {
@Override
public void run() {
SamplingProfilerIntegration.writeSnapshot("system_server", null);
}
}, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
} // Mmmmmm... more memory!
VMRuntime.getRuntime().clearGrowthLimit(); // The system server has to run all of the time, so it needs to be
// as efficient as possible with its memory usage.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); // Some devices rely on runtime fingerprint generation, so make sure
// we've defined it before booting further.
Build.ensureFingerprintProperty(); // Within the system server, it is an error to access Environment paths without
// explicitly specifying a user.
Environment.setUserRequired(true); // Ensure binder calls into the system always run at foreground priority.
BinderInternal.disableBackgroundScheduling(true); // Prepare the main looper thread (this thread).
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper(); // Initialize native services.
System.loadLibrary("android_servers"); // Check whether we failed to shut down last time we tried.
// This call may not return.
performPendingShutdown(); // Initialize the system context.
createSystemContext(); // Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); // Start services.
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} // For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode for system server main thread.");
} // Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
- 然后下面的代码是:
// Initialize the system context.
createSystemContext(); // Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); // Start services.
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
3.4 run方法中createSystemContext()解析
- 调用createSystemContext()方法:
- 可以看到在SystemServer进程中也存在着Context对象,并且是通过ActivityThread.systemMain方法创建context的,这一部分的逻辑以后会通过介绍Activity的启动流程来介绍,这里就不在扩展,只知道在SystemServer进程中也需要创建Context对象。
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
}
3.5 mSystemServiceManager的创建
- 看run方法中,通过SystemServiceManager的构造方法创建了一个新的SystemServiceManager对象,我们知道SystemServer进程主要是用来构建系统各种service服务的,而SystemServiceManager就是这些服务的管理对象。
- 然后调用:
- 将SystemServiceManager对象保存SystemServer进程中的一个数据结构中。
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
- 最后开始执行:
// Start services.
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
- 里面主要涉及了是三个方法:
- startBootstrapServices() 主要用于启动系统Boot级服务
- startCoreServices() 主要用于启动系统核心的服务
- startOtherServices() 主要用于启动一些非紧要或者是非需要及时启动的服务
- 里面主要涉及了是三个方法:
4.启动服务
4.1 启动哪些服务
- 在开始执行启动服务之前总是会先尝试通过socket方式连接Zygote进程,在成功连接之后才会开始启动其他服务。

4.2 启动服务流程源码分析
- 首先看一下startBootstrapServices方法:
private void startBootstrapServices() {
Installer installer = mSystemServiceManager.startService(Installer.class); mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer); mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); mActivityManagerService.initPowerManagement(); // Manages LEDs and display backlight so we need it to bring up the display.
mSystemServiceManager.startService(LightsService.class); // Display manager is needed to provide display metrics before package manager
// starts up.
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); // We need the default display before we can initialize the package manager.
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); // Only run "core" apps if we're encrypting the device.
String cryptState = SystemProperties.get("vold.decrypt");
if (ENCRYPTING_STATE.equals(cryptState)) {
Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
mOnlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
Slog.w(TAG, "Device encrypted - only parsing core apps");
mOnlyCore = true;
} // Start the package manager.
Slog.i(TAG, "Package Manager");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager(); Slog.i(TAG, "User Service");
ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance()); // Initialize attribute cache used to cache resources from packages.
AttributeCache.init(mSystemContext); // Set up the Application instance for the system process and get started.
mActivityManagerService.setSystemProcess(); // The sensor service needs access to package manager service, app ops
// service, and permissions service, therefore we start it after them.
startSensorService();
}
- 先执行:
Installer installer = mSystemServiceManager.startService(Installer.class);
- mSystemServiceManager是系统服务管理对象,在main方法中已经创建完成,这里我们看一下其startService方法的具体实现:
- 可以看到通过反射器构造方法创建出服务类,然后添加到SystemServiceManager的服务列表数据中,最后调用了service.onStart()方法,因为传递的是Installer.class
public <T extends SystemService> T startService(Class<T> serviceClass) {
final String name = serviceClass.getName();
Slog.i(TAG, "Starting " + name); // Create the service.
if (!SystemService.class.isAssignableFrom(serviceClass)) {
throw new RuntimeException("Failed to create " + name
+ ": service must extend " + SystemService.class.getName());
}
final T service;
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service could not be instantiated", ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (NoSuchMethodException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service constructor threw an exception", ex);
} // Register it.
mServices.add(service); // Start it.
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + name
+ ": onStart threw an exception", ex);
}
return service;
}
- 看一下Installer的onStart方法:
- 很简单就是执行了mInstaller的waitForConnection方法,这里简单介绍一下Installer类,该类是系统安装apk时的一个服务类,继承SystemService(系统服务的一个抽象接口),需要在启动完成Installer服务之后才能启动其他的系统服务。
@Override
public void onStart() {
Slog.i(TAG, "Waiting for installd to be ready.");
mInstaller.waitForConnection();
}
- 然后查看waitForConnection()方法:
- 通过追踪代码可以发现,其在不断的通过ping命令连接Zygote进程(SystemServer和Zygote进程通过socket方式通讯,其他进程通过Binder方式通讯)
public void waitForConnection() {
for (;;) {
if (execute("ping") >= 0) {
return;
}
Slog.w(TAG, "installd not ready");
SystemClock.sleep(1000);
}
}
- 继续看startBootstrapServices方法:
- 这段代码主要是用于启动ActivityManagerService服务,并为其设置SysServiceManager和Installer。ActivityManagerService是系统中一个非常重要的服务,Activity,service,Broadcast,contentProvider都需要通过其余系统交互。
// Activity manager runs the show.
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
- 首先看一下Lifecycle类的定义:
- 可以看到其实ActivityManagerService的一个静态内部类,在其构造方法中会创建一个ActivityManagerService,通过刚刚对Installer服务的分析我们知道,SystemServiceManager的startService方法会调用服务的onStart()方法,而在Lifecycle类的定义中我们看到其onStart()方法直接调用了mService.start()方法,mService是Lifecycle类中对ActivityManagerService的引用
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService; public Lifecycle(Context context) {
super(context);
mService = new ActivityManagerService(context);
} @Override
public void onStart() {
mService.start();
} public ActivityManagerService getService() {
return mService;
}
}
4.3 启动部分服务
- 启动PowerManagerService服务:
- 启动方式跟上面的ActivityManagerService服务相似都会调用其构造方法和onStart方法,PowerManagerService主要用于计算系统中和Power相关的计算,然后决策系统应该如何反应。同时协调Power如何与系统其它模块的交互,比如没有用户活动时,屏幕变暗等等。
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
- 然后是启动LightsService服务
- 主要是手机中关于闪光灯,LED等相关的服务;也是会调用LightsService的构造方法和onStart方法;
mSystemServiceManager.startService(LightsService.class);
- 然后是启动DisplayManagerService服务
- 主要是手机显示方面的服务
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
- 然后是启动PackageManagerService,该服务也是android系统中一个比较重要的服务
- 包括多apk文件的安装,解析,删除,卸载等等操作。
- 可以看到PackageManagerService服务的启动方式与其他服务的启动方式有一些区别,直接调用了PackageManagerService的静态main方法
Slog.i(TAG, "Package Manager");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
- 看一下其main方法的具体实现:
- 可以看到也是直接使用new的方式创建了一个PackageManagerService对象,并在其构造方法中初始化相关变量,最后调用了ServiceManager.addService方法,主要是通过Binder机制与JNI层交互
public static PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore);
ServiceManager.addService("package", m);
return m;
}
- 然后查看startCoreServices方法:
- 可以看到这里启动了BatteryService(电池相关服务),UsageStatsService,WebViewUpdateService服务等。
private void startCoreServices() {
// Tracks the battery level. Requires LightService.
mSystemServiceManager.startService(BatteryService.class); // Tracks application usage stats.
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
// Update after UsageStatsService is available, needed before performBootDexOpt.
mPackageManagerService.getUsageStatsIfNoPackageUsageInfo(); // Tracks whether the updatable WebView is in a ready state and watches for update installs.
mSystemServiceManager.startService(WebViewUpdateService.class);
}
总结:
- SystemServer进程是android中一个很重要的进程由Zygote进程启动;
- SystemServer进程主要用于启动系统中的服务;
- SystemServer进程启动服务的启动函数为main函数;
- SystemServer在执行过程中首先会初始化一些系统变量,加载类库,创建Context对象,创建SystemServiceManager对象等之后才开始启动系统服务;
- SystemServer进程将系统服务分为三类:boot服务,core服务和other服务,并逐步启动
- SertemServer进程在尝试启动服务之前会首先尝试与Zygote建立socket通讯,只有通讯成功之后才会开始尝试启动服务;
- 创建的系统服务过程中主要通过SystemServiceManager对象来管理,通过调用服务对象的构造方法和onStart方法初始化服务的相关变量;
- 服务对象都有自己的异步消息对象,并运行在单独的线程中;
参考博客
- https://www.jianshu.com/p/064136533445
- http://blog.csdn.net/qq_23547831/article/details/51104873
- http://www.xuebuyuan.com/2178651.html
- https://www.jianshu.com/p/e69d22ec0582
- http://blog.csdn.net/luoshengyang/article/details/6768304
- http://blog.csdn.net/ericming200409/article/details/45566153
关于其他内容介绍
01.关于博客汇总链接
02.关于我的博客
- 我的个人站点:www.yczbj.org,www.ycbjie.cn
- github:https://github.com/yangchong211
- 知乎:https://www.zhihu.com/people/yang-chong-69-24/pins/posts
- 简书:http://www.jianshu.com/u/b7b2c6ed9284
- csdn:http://my.csdn.net/m0_37700275
- 喜马拉雅听书:http://www.ximalaya.com/zhubo/71989305/
- 开源中国:https://my.oschina.net/zbj1618/blog
- 泡在网上的日子:http://www.jcodecraeer.com/member/content_list.php?channelid=1
- 邮箱:yangchong211@163.com
- 阿里云博客:https://yq.aliyun.com/users/article?spm=5176.100- 239.headeruserinfo.3.dT4bcV
- segmentfault头条:https://segmentfault.com/u/xiangjianyu/articles
App启动流程的更多相关文章
- Android Activity启动流程, app启动流程,APK打包流程, APK安装过程
1.Activity启动流程 (7.0版本之前) 从startActivity()开始,最终都会调用startActivityForResult() 在该方法里面会调用Instrumentation. ...
- 女儿拿着小天才电话手表问我App启动流程
前言 首先,new一个女儿, var mDdaughter = new 女儿("6岁","漂亮可爱","健康乖巧","最喜欢玩小天 ...
- iOS app启动流程
最近看了些Runtime Runloop的一些知识.边看边摸索.看到群里有人在问 一些面试题.其中就提到了app的启动流程. 所以这里也研究小结一下,以供自己学习备用. 1.项目要运行,就要有入口. ...
- 一触即发 App启动优化最佳实践
一触即发 App启动优化最佳实践 本文在 DiyCode 和 CSDN个人博客 同时首发,关注作者的 DiyCode帐号 或者 作者微博 可第一时间收到新文章推送. 文中的很多图都是Google性能优 ...
- Android进阶系列之源码分析Activity的启动流程
美女镇楼,辟邪! 源码,是一个程序猿前进路上一个大的而又不得不去翻越障碍,我讨厌源码,看着一大堆.5000多行,要看完得啥时候去了啊.不过做安卓的总有这一天,自从踏上这条不归路,我就认命了.好吧,我慢 ...
- iOS开发app启动原理及视图和控制器的函数调用顺序
main()函数是整个程序的入口,在程序启动之前,系统会调用exec()函数.在Unix中exec和system的不同在于,system是用shell来调用程序,相当于fork+exec+waitpi ...
- `cocos2dx非完整` 游戏架构缩影 添加启动流程
这期的话题可能不是很好, 我没有想到很好的词句去更好的表达. 我一直都是很固执的认为, 同一类型的游戏,在开发做的前期工作上面其实都是可以复用的,也就是大同小异的.从游戏启动,启动日志,启动检查,检查 ...
- Android 一个app启动另一个app
最近,一个app启动另一个app,这个玩法挺火的嘛,有没有试过更新QQ到5.1版本,QQ的健康里面就可以添加其他app,实现从QQ跳转到其他app应用.这个挺好玩的,一下子带来了多少流量啊. 一.先来 ...
- activiti自定义流程之Spring整合activiti-modeler5.16实例(六):启动流程
注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建 (2)创建流程模型:activiti自定义流程之Spring ...
- lk启动流程详细分析
转载请注明来源:cuixiaolei的技术博客 这篇文章是lk启动流程分析(以高通为例),将会详细介绍下面的内容: 1).正常开机引导流程 2).recovery引导流程 3).fastboot引导流 ...
随机推荐
- android mvvm实例解析
MVVM架构,将整个应用分为三层,View层,VM层,Model层.其中View层单向引用VM层,VM层单向引用Model层.如上图. 单向引用,而非双向引用,这是MVVM与MVP最大的区别.View ...
- 【Unity3D】固定管线着色器二
1 前言 固定管线着色器一 中介绍了 Shader 中外部属性.光照.贴图等基础用法,本文将进一步讲解固定管线着色器,介绍正面与反面剔除.Alpha 测试.深度测试.混合.渲染队列等用法.渲染管线 ...
- Java并发编程实例--20.使用Semaphores(信号量)控制资源的并发读取
前面我们介绍了2种同步机制: 1)使用synchronized关键字 2)使用Lock接口及其实现类: ReentrantLock,ReentrantReadWriteLock.ReadLock, a ...
- C++ 多线程的错误和如何避免(13)
在 async 任务中抛出的异常会被 std::future::get() 触发 #include <future> #include <iostream> int main( ...
- Go微服务框架go-kratos实战学习07:consul 作为服务注册和发现中心
一.Consul 简介 consul 是什么 HashiCorp Consul 是一种服务网络解决方案,它能够管理服务之间以及跨本地和多云环境和运行时的安全网络连接.Consul 它能提供服务发现.服 ...
- Python2升级到Python3
操作系统环境:CentOS Linux release 7.4.1708 (Core). 系统默认Python版本为2.7. 升级前的版本信息: [root@cch-spider-web1 ~]# l ...
- 理解[].forEach.call()并说明为什么要使用[].forEach.call()
[].forEach.call(elems, callback) 相当于: Array.prototype.forEach.call(elems, callback) 又相当于: function(e ...
- 串口通信RXTXcomm使用
一.串口通信原理 串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节. 尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时 ...
- OpenCV开发笔记(五十八):红胖子8分钟带你深入了解图像的矩(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- 项目实战:Qt管道焊接参数条码打印系统(条码打印机TSC 244 Pro、打印条码、打印中文、打印字符、多张连续打印)
需求 电脑端通过条码打印机TSC-TTP244 Pro: 1. 打印出尺寸为60*30cm 2. 条码打印机TSC-TTP244 Pro 不干胶纸 (不需要碳带,热敏纸) 3. window ...