Android APP启动流程

简介: 学习笔记

手机启动

Android手机在开机Linux内核启动的时候,会加载system/core/init/init.rc文件,启动init进程,这个是Android特有的初始化程序,主要负责

  • 各种复杂工作
  • 负责开关机画面
  • 文件系统的创建和挂载
  • 启动Zygote(孵化器)进程
  • 启动ServiceManager,它是Binder服务管理器,管理所有Android系统服务

fork Zygote

在启动init进程后会fork Zygote进程,它是一个孵化器进程,它的main函数会创建好环境并且等待孵化,接到指令后就会开始fork子进程

创建一个server端的socket, name为zynote,用于和客户端进程通信

预加载类和资源,提高应用启动速度

启动SystemServer进程

监听socket,当有一个应用程序启动时,就会向它发出请求,然后zygote进程fock自己来创建的一个新的子进程。

所以说Android内所有的应用其实都是Zygote的子进程

SystemServer

SystemServer是由zygote进程fork出来的第一个进程,SystemServer和Zygote是Android Framework最重要的2个进程。 系统里面重要的服务都是在这个进程里面开启的,比如ActivityManagerService(AMS)、PackageManagerService(PMS)、WindowManagerService(WMS)。

应用启动流程基本是围绕着ActivityManagerService和ActivityThread展开。

并且负责启动并且管理整个framework。

ActivityManagerService

ActivityManagerService,简称AMS,服务端对象,负责系统中所有Activity的生命周期。

并且他在SystemServer进程开启的时候,就会直接跟着一起初始化

应用启动

涉及进程

Android开发中,我们可以通过Package包名和Activity类名,来打开一个APP。实际上,项目里的业务代码startActivity()方法并不是直接创建进程、拉起APP的。而是通过一系列的调用,把请求传递给SystemServer的AMS。AMS收到来自客户端的请求后,再通知zygote进程来fork一个新进程,来开启我们的目标APP。APP中所有Activity的生命周期过程,都由AMS(SystemServer进程)统一调度,并在APP自身进程中具体完成。

所以打开应用总共涉及了三个进程:Zygote进程、AMS进程、APP进程

App进程与AMS通过Binder机制进行跨进程通信

AMS(SystemServer进程)与zygote通过Socket进行跨进程通信。

在Android系统中,任何一个Activity的启动都是由AMS和App进程(主要是ActivityThread)相互配合来完成的。AMS服务统一调度系统中所有进程的Activity启动,而每个Activity的启动过程则由其所属的进程具体来完成。

启动步骤

1、activity中的startActivity方法最终都会通过拿到ATSM的代理IActivityTaskManager调用的startActivity;

2、之后进入system server进程中的ATMS startActivity,ATMS 经过收集Intent信息,然后使用ActivityStackSupervisor.startSpecificActivityLocked,如果进程已经存在,则直接使用realStartActivityLocked,通过App的binder客户端的代理ApplicationThread调用回到bindApplication,走入Activity的启动流程;如果进程不存在则通过socket链接Zygote,请求fork新的进程;

3、App进程创建完成后,进程启动会调用ActivityThread.main方法,初始化主线程Handler,接着走入attach方法,然后通过AMS的代理调用AMS的attachApplication方法,并将App进程的通信代理ApplicationThread传入AMS;

4、AMS获取到ATMS调用ApplicationThread的bindApplication回到App进程的ActivityThread.ApplicationThread.bindApplication方法中,然后使用Handler切换到主线程执行handleBindApplication,这里初始化了App的进程名字、时间,用户的硬件配置,包括App的文件系统,创建了App的Context实例,Instrumentation实例,调用App的onCreate回调方法,同时告诉AMS APP初始化工作完毕;

5、AMS接着会调用ATMS的attachApplication,最后调用ClientLifecycleManager的scheduleTransaction方法,通过App的Binder代理ApplicationThread回到ActivityThread;

6、进入ActivityThread.ApplicationThread.scheduleTransaction方法之后就进入了Activity的onStart、onResume回调

网络异常,图片无法展示
|

网络异常,图片无法展示
|

流程

ActivityThread

一个应用,在被点击后首先要fork出一个Zygote进程,接下来执行ActivityThread.main

public static void main(String[] args) {

   ActivityThread thread = new ActivityThread();

   thread.attach(false, startSeq);

   if (sMainThreadHandler == null) {

       sMainThreadHandler = thread.getHandler();

   }

   if (false) {

       Looper.myLooper().setMessageLogging(new

               LogPrinter(Log.DEBUG, "ActivityThread"));

   }

   // End of event ActivityThreadMain.

   Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

   Looper.loop();

   throw new RuntimeException("Main thread loop unexpectedly exited");

}


然后调用ActivityThread的attach方法,然后将activity和AMS通信的Binder代理IApplicationThread实例传入AMS

@UnsupportedAppUsage

private void attach(boolean system, long startSeq) {

   sCurrentActivityThread = this;

   mSystemThread = system;

   if (!system) {

       android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",

                                               UserHandle.myUserId());

       RuntimeInit.setApplicationObject(mAppThread.asBinder());

       final IActivityManager mgr = ActivityManager.getService();

       try {

           mgr.attachApplication(mAppThread, startSeq);

       } catch (RemoteException ex) {

           throw ex.rethrowFromSystemServer();

       }

       // Watch for getting close to heap limit.

       BinderInternal.addGcWatcher(new Runnable() {

           @Override public void run() {

               if (!mSomeActivitiesChanged) {

                   return;

               }

               Runtime runtime = Runtime.getRuntime();

               long dalvikMax = runtime.maxMemory();

               long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();

               if (dalvikUsed > ((3*dalvikMax)/4)) {

                   if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)

                           + " total=" + (runtime.totalMemory()/1024)

                           + " used=" + (dalvikUsed/1024));

                   mSomeActivitiesChanged = false;

                   try {

                       ActivityTaskManager.getService().releaseSomeActivities(mAppThread);

                   } catch (RemoteException e) {

                       throw e.rethrowFromSystemServer();

                   }

               }

           }

       });

   }  

}

AMS

接着进入AMS进程,ActivityManagerService.attachApplicationLocked

private final boolean attachApplicationLocked(IApplicationThread thread,

           int pid, int callingUid, long startSeq) {

           if (app.isolatedEntryPoint != null) {

               // This is an isolated process which should just call an entry point instead of

               // being bound to an application.

               thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);

           } else if (instr2 != null) {

               thread.bindApplication(processName, appInfo, providers,

                       instr2.mClass,

                       profilerInfo, instr2.mArguments,

                       instr2.mWatcher,

                       instr2.mUiAutomationConnection, testMode,

                       mBinderTransactionTrackingEnabled, enableTrackAllocation,

                       isRestrictedBackupMode || !normalMode, app.isPersistent(),

                       new Configuration(app.getWindowProcessController().getConfiguration()),

                       app.compat, getCommonServicesLocked(app.isolated),

                       mCoreSettingsObserver.getCoreSettingsLocked(),

                       buildSerial, autofillOptions, contentCaptureOptions);

           } else {

               thread.bindApplication(processName, appInfo, providers, null, profilerInfo,

                       null, null, null, testMode,

                       mBinderTransactionTrackingEnabled, enableTrackAllocation,

                       isRestrictedBackupMode || !normalMode, app.isPersistent(),

                       new Configuration(app.getWindowProcessController().getConfiguration()),

                       app.compat, getCommonServicesLocked(app.isolated),

                       mCoreSettingsObserver.getCoreSettingsLocked(),

                       buildSerial, autofillOptions, contentCaptureOptions);

           }

       } catch (Exception e) {

       }

       // See if the top visible activity is waiting to run in this process...

       if (normalMode) {

           try {

               didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());

           } catch (Exception e) {

               Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);

               badApp = true;

           }

       }

       // Find any services that should be running in this process...

       if (!badApp) {

           try {

               didSomething |= mServices.attachApplicationLocked(app, processName);

               checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");

           } catch (Exception e) {

               Slog.wtf(TAG, "Exception thrown starting services in " + app, e);

               badApp = true;

           }

       }

       return true;

   }

thread.bindApplication:该方法主要讲App进程的配置信息通过IApplicationThread Binder通信回传到ActivityThread中;

mAtmInternal.attachApplication:mAtmInternal实际就是ActivityTaskManager的实例,通过LocalServices加载;

mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);

1

那么这里相当于走到了ActivityTaskManagerServer的attachApplication中;

bindApplication

@Override

       public final void bindApplication(String processName, ApplicationInfo appInfo,

               ProviderInfoList providerList, ComponentName instrumentationName,

               ProfilerInfo profilerInfo, Bundle instrumentationArgs,

               IInstrumentationWatcher instrumentationWatcher,

               IUiAutomationConnection instrumentationUiConnection, int debugMode,

               boolean enableBinderTracking, boolean trackAllocation,

               boolean isRestrictedBackupMode, boolean persistent, Configuration config,

               CompatibilityInfo compatInfo, Map services, Bundle coreSettings,

               String buildSerial, AutofillOptions autofillOptions,

               ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges) {

           setCoreSettings(coreSettings);

           AppBindData data = new AppBindData();

           data.processName = processName;

           .....

           sendMessage(H.BIND_APPLICATION, data);

       }

这里的bindApplication主要初始化了AppBindData,然后发送BIND_APPLICATION给APP的主线程BIND_APPLICATION,最后执行了handleBindApplication

case BIND_APPLICATION:

                   Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");

                   AppBindData data = (AppBindData)msg.obj;

                   handleBindApplication(data);

                   Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

                   break;

Application的onCreate方法

private void handleBindApplication(AppBindData data) {

         mBoundApplication = data;

       mConfiguration = new Configuration(data.config);

       mCompatConfiguration = new Configuration(data.config);

        if (data.initProfilerInfo != null) {

           mProfiler.profileFile = data.initProfilerInfo.profileFile;

           mProfiler.profileFd = data.initProfilerInfo.profileFd;

           mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;

           mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;

           mProfiler.streamingOutput = data.initProfilerInfo.streamingOutput;

           if (data.initProfilerInfo.attachAgentDuringBind) {

               agent = data.initProfilerInfo.agent;

           }

       }

mInstrumentationPackageName = ii.packageName;

           mInstrumentationAppDir = ii.sourceDir;

           mInstrumentationSplitAppDirs = ii.splitSourceDirs;

           mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);

           mInstrumentedAppDir = data.info.getAppDir();

           mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();

           mInstrumentedLibDir = data.info.getLibDir();

            mInstrumentation.callApplicationOnCreate(app);

}


这个方法主要在App进程中对App的一些硬件资源配置申请的属性、App的文件夹等完成App基本信息的初始化

并且

mAtmInternal.attachApplication最终会调用mRootActivityContainer.attachApplication(wpc)

RootActivityContainer.attachApplication

boolean attachApplication(WindowProcessController app) throws RemoteException {

   final String processName = app.mName;

   boolean didSomething = false;

   for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {

       final ActivityDisplay display = mActivityDisplays.get(displayNdx);

       final ActivityStack stack = display.getFocusedStack();

       if (stack != null) {

           stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);

           //获取前台栈顶第一个非finishing的Activity

           final ActivityRecord top = stack.topRunningActivityLocked();

           final int size = mTmpActivityList.size();

           for (int i = 0; i < size; i++) {

               final ActivityRecord activity = mTmpActivityList.get(i);

               if (activity.app == null && app.mUid == activity.info.applicationInfo.uid

                       && processName.equals(activity.processName)) {

                   try {

                   //真正启动Activity

                       if (mStackSupervisor.realStartActivityLocked(activity, app,

                               top == activity /* andResume */, true /* checkConfig */)) {

                           didSomething = true;

                       }

                   } catch (RemoteException e) {

                       Slog.w(TAG, "Exception in new application when starting activity "

                               + top.intent.getComponent().flattenToShortString(), e);

                       throw e;

                   }

               }

           }

       }

   }

   if (!didSomething) {

       ensureActivitiesVisible(null, 0, false /* preserve_windows */);

   }

   return didSomething;

}

接着调用ActivityStackSupervisor开始创建Activity

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,

           boolean andResume, boolean checkConfig) throws RemoteException {

       try {

           r.startFreezingScreenLocked(app, 0);

           //启动tick,收集应用启动慢的信息

           // schedule launch ticks to collect information about slow apps.

           r.startLaunchTickingLocked();

           r.setProcess(app);

           try {

               //创建Activity启动事务

               // Create activity launch transaction.

               final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,

                       r.appToken);

               clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),

                       System.identityHashCode(r), r.info,

                       // TODO: Have this take the merged configuration instead of separate global

                       // and override configs.

                       mergedConfiguration.getGlobalConfiguration(),

                       mergedConfiguration.getOverrideConfiguration(), r.compat,

                       r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,

                       r.persistentState, results, newIntents, mService.isNextTransitionForward(),

                       profilerInfo));

               //设置目标事务的状态为onResume

               // Set desired final state.

               final ActivityLifecycleItem lifecycleItem;

               if (andResume) {

                   lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());

               } else {

                   lifecycleItem = PauseActivityItem.obtain();

               }

               clientTransaction.setLifecycleStateRequest(lifecycleItem);

               //通过transaciton方式开始activity生命周期,onCreate,onStart,onResume

               // Schedule transaction.

               mService.getLifecycleManager().scheduleTransaction(clientTransaction);

           } catch (RemoteException e) {

           }

       } finally {

           endDeferResume();

       }

       return true;

   }


在这个方法中间ClientLifecycleManager.scheduleTransaction最终会调用ClientTransaction的schedule方法,然后这个方法实际上会回调回ActivityThread

运用了IApplicationThread ,也就是AMS和ActivityThread通信的桥梁

APP.onCreate

所以我们调用

@Override

 public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {

       ActivityThread.this.scheduleTransaction(transaction);

 }

 

void scheduleTransaction(ClientTransaction transaction) {

     transaction.preExecute(this);

     sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);

}  


。。。。。。(最后再调用了几个方法,根据代码走就可以了没啥特殊的这里就不放了)

最后调用了activity.attach方法。

在这期间,ActivityThread做了这样几件事

通过反射创建Activity实例,这是通过Instrumentation.newActivity方法实现的;

调用Activity的onCreate回调;

通过Activity.attach方法,实例化Window对象;


总结:


点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;

system_server进程接收到请求后,向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()等方法

相关文章
|
22天前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android多线程编程的重要性及其实现方法,涵盖了基本概念、常见线程类型(如主线程、工作线程)以及多种多线程实现方式(如`Thread`、`HandlerThread`、`Executors`、Kotlin协程等)。通过合理的多线程管理,可大幅提升应用性能和用户体验。
39 15
一个Android App最少有几个线程?实现多线程的方式有哪些?
|
9天前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
讲解Activity的启动流程了,Activity的启动流程相对复杂一下,涉及到了Activity中的生命周期方法,涉及到了Android体系的CS模式,涉及到了Android中进程通讯Binder机制等等, 首先介绍一下Activity,这里引用一下Android guide中对Activity的介绍:
25 4
|
9天前
|
存储 开发工具 Android开发
使用.NET MAUI开发第一个安卓APP
【9月更文挑战第24天】使用.NET MAUI开发首个安卓APP需完成以下步骤:首先,安装Visual Studio 2022并勾选“.NET Multi-platform App UI development”工作负载;接着,安装Android SDK。然后,创建新项目时选择“.NET Multi-platform App (MAUI)”模板,并仅针对Android平台进行配置。了解项目结构,包括`.csproj`配置文件、`Properties`配置文件夹、平台特定代码及共享代码等。
|
13天前
|
XML Android开发 数据格式
🌐Android国际化与本地化全攻略!让你的App走遍全球无障碍!🌍
在全球化背景下,实现Android应用的国际化与本地化至关重要。本文以一款旅游指南App为例,详细介绍如何通过资源文件拆分与命名、适配布局与方向、处理日期时间及货币格式、考虑文化习俗等步骤,完成多语言支持和本地化调整。通过邀请用户测试并收集反馈,确保应用能无缝融入不同市场,提升用户体验与满意度。
35 3
|
24天前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android应用开发中的多线程编程,涵盖基本概念、常见实现方式及最佳实践。主要内容包括主线程与工作线程的作用、多线程的多种实现方法(如 `Thread`、`HandlerThread`、`Executors` 和 Kotlin 协程),以及如何避免内存泄漏和合理使用线程池。通过有效的多线程管理,可以显著提升应用性能和用户体验。
38 10
|
8天前
|
XML 数据库 Android开发
10分钟手把手教你用Android手撸一个简易的个人记账App
该文章提供了使用Android Studio从零开始创建一个简单的个人记账应用的详细步骤,包括项目搭建、界面设计、数据库处理及各功能模块的实现方法。
|
9天前
|
Android开发 开发者
Android面试之Activity启动流程简述
每个Android开发者都熟悉的Activity,但你是否了解它的启动流程呢?本文将带你深入了解。启动流程涉及四个关键角色:Launcher进程、SystemServer的AMS、应用程序的ActivityThread及Zygote进程。核心在于AMS与ActivityThread间的通信。文章详细解析了从Launcher启动Activity的过程,包括通过AIDL获取AMS、Zygote进程启动以及ActivityThread与AMS的通信机制。接着介绍了如何创建Application及Activity的具体步骤。整体流程清晰明了,帮助你更深入理解Activity的工作原理。
16 0
|
2月前
|
Android开发 iOS开发 C#
Xamarin:用C#打造跨平台移动应用的终极利器——从零开始构建你的第一个iOS与Android通用App,体验前所未有的高效与便捷开发之旅
【8月更文挑战第31天】Xamarin 是一个强大的框架,允许开发者使用单一的 C# 代码库构建高性能的原生移动应用,支持 iOS、Android 和 Windows 平台。作为微软的一部分,Xamarin 充分利用了 .NET 框架的强大功能,提供了丰富的 API 和工具集,简化了跨平台移动应用开发。本文通过一个简单的示例应用介绍了如何使用 Xamarin.Forms 快速创建跨平台应用,包括设置开发环境、定义用户界面和实现按钮点击事件处理逻辑。这个示例展示了 Xamarin.Forms 的基本功能,帮助开发者提高开发效率并实现一致的用户体验。
78 0
|
缓存 开发工具 Android开发
Android App性能评测分析-启动时间篇
1、前言 随着项目版本的迭代,App的性能问题会逐渐暴露出来,而好的用户体验与性能表现紧密相关,性能问题从应用的启动优化开始,下面会根据实际app性能测试案例,进行app性能评测之启动时间的分析和总结。
4249 0
|
Shell Linux 测试技术
Android App性能评测分析-cpu占用篇
1、前言 很多时候在使用APP的时候,手机可能会发热发烫。这是因为CPU使用率过高,CPU过于繁忙,会使整个手机无法响应用户,整体性能降低,用户体验就会很差,也容易引起ANR等等一系列问题。
5110 0
下一篇
无影云桌面