Android应用程序启动过程
有没有想过,当我们点击桌面应用程序图标是怎样打开APP启动应用程序的呢?
当我们点击应用图标会调用Launcher的startActivitySafely()方法,方法实现如下,其实是调用的startActivity()方法。
public boolean startActivitySafely(View v, Intent intent, Object tag) { ... try { success = startActivity(v, intent, tag); } catch (ActivityNotFoundException e) { Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e); } return success; }
private boolean startActivity(View v, Intent intent, Object tag) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { ... if (user == null || user.equals(UserHandleCompat.myUserHandle())) { StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy(); try { StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll() .penaltyLog().build()); startActivity(intent, optsBundle); } finally { StrictMode.setVmPolicy(oldPolicy); } } else { launcherApps.startActivityForProfile(intent.getComponent(), user, intent.getSourceBounds(), optsBundle); } return true; } catch (SecurityException e) { ... } return false; }
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),这样根Activity会在新的任务栈中启动。
- 点击App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;
- system_server进程接收到请求后,向zygote进程发送创建进程的请求,Android所有应用程序都是zygote的子进程;
- Zygote进程fork出新的子进程,即App进程;
- App进程通过Binder IPC向sytem_server进程发起attachApplication请求;
- system_server进程在收到请求后,进行一系列准备工作后再通过Binder IPC向App进程发送scheduleLaunchActivity请求;
- App进程的binder线程(ApplicationThread在收到请求后通过handler向主线程发送LAUNCH_ACTIVITY消息;
- 主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法;
- App便正式启动,开始进入Activity生命周期,UI渲染结束后便看到App的主界面。