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()等方法

相关文章
|
7月前
|
Android开发 数据安全/隐私保护 开发者
Android自定义view之模仿登录界面文本输入框(华为云APP)
本文介绍了一款自定义输入框的实现,包含静态效果、hint值浮动动画及功能扩展。通过组合多个控件完成界面布局,使用TranslateAnimation与AlphaAnimation实现hint文字上下浮动效果,支持密码加密解密显示、去除键盘回车空格输入、光标定位等功能。代码基于Android平台,提供完整源码与attrs配置,方便复用与定制。希望对开发者有所帮助。
130 0
|
10月前
|
JavaScript 前端开发 Android开发
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
348 13
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
4月前
|
存储 Java PHP
轻量化短视频电商直播带货APP源码全解析:核心功能与设计流程​
在电商直播热潮下,开发专属直播带货APP成为抢占市场关键。本文详解原生开发轻量化APP的核心功能与全流程设计,涵盖用户登录、商品浏览、直播互动、购物车、订单及售后功能,并介绍安卓端Java、苹果端Object-C、后台PHP的技术实现,助力打造高效优质的直播电商平台。
|
5月前
|
存储 Android开发 数据安全/隐私保护
Thanox安卓系统增加工具下载,管理、阻止、限制后台每个APP运行情况
Thanox是一款Android系统管理工具,专注于权限、后台启动及运行管理。支持应用冻结、系统优化、UI自定义和模块管理,基于Xposed框架开发,安全可靠且开源免费,兼容Android 6.0及以上版本。
445 4
|
8月前
|
数据采集 JSON 网络安全
移动端数据抓取:Android App的TLS流量解密方案
本文介绍了一种通过TLS流量解密技术抓取知乎App热榜数据的方法。利用Charles Proxy解密HTTPS流量,分析App与服务器通信内容;结合Python Requests库模拟请求,配置特定请求头以绕过反爬机制。同时使用代理IP隐藏真实IP地址,确保抓取稳定。最终成功提取热榜标题、内容简介、链接等信息,为分析热点话题和用户趋势提供数据支持。此方法也可应用于其他Android App的数据采集,但需注意选择可靠的代理服务。
332 11
移动端数据抓取:Android App的TLS流量解密方案
|
9月前
|
安全 算法 小程序
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
563 28
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
|
9月前
|
小程序
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
602 1
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
|
8月前
|
NoSQL 应用服务中间件 PHP
布谷一对一直播源码android版环境配置流程及功能明细
部署需基于 CentOS 7.9 系统,硬盘不低于 40G,使用宝塔面板安装环境,包括 PHP 7.3(含 Redis、Fileinfo 扩展)、Nginx、MySQL 5.6、Redis 和最新 Composer。Swoole 扩展需按步骤配置。2021.08.05 后部署需将站点目录设为 public 并用 ThinkPHP 伪静态。开发环境建议 Windows 操作系统与最新 Android Studio,基础配置涉及 APP 名称修改、接口域名更换、包名调整及第三方登录分享(如 QQ、微信)的配置,同时需完成阿里云与腾讯云相关设置。
|
9月前
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
|
10月前
|
小程序 数据安全/隐私保护 开发者
【02】微信支付商户申请下户到配置完整流程-微信开放平台申请APP应用-微信商户支付绑定appid-公众号和小程序分别申请appid-申请+配置完整流程-优雅草卓伊凡
【02】微信支付商户申请下户到配置完整流程-微信开放平台申请APP应用-微信商户支付绑定appid-公众号和小程序分别申请appid-申请+配置完整流程-优雅草卓伊凡
647 3