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

相关文章
|
1月前
|
XML Java 数据库
安卓项目:app注册/登录界面设计
本文介绍了如何设计一个Android应用的注册/登录界面,包括布局文件的创建、登录和注册逻辑的实现,以及运行效果的展示。
140 0
安卓项目:app注册/登录界面设计
|
16天前
|
监控 安全 开发者
山东布谷科技:关于直播源码|语音源码|一对一直播源码提交App Store的流程及重构经验
分享提交直播源码,一对一直播源码,语音源码到Appstore的重构经验!
|
25天前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
70 6
|
23天前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
|
26天前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
Android面试高频知识点(4) 详解Activity的启动流程
25 3
|
27天前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
24 2
|
1月前
|
XML 前端开发 Android开发
Android View的绘制流程和原理详细解说
Android View的绘制流程和原理详细解说
35 3
|
1月前
|
安全 开发者 UED
APP上架到应用商店需要哪些流程?
APP上架是一个涉及多个步骤和准备工作的过程,主要包括准备上架资料和遵循上架流程两个方面。
86 1
|
26天前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
17 0
|
2月前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
讲解Activity的启动流程了,Activity的启动流程相对复杂一下,涉及到了Activity中的生命周期方法,涉及到了Android体系的CS模式,涉及到了Android中进程通讯Binder机制等等, 首先介绍一下Activity,这里引用一下Android guide中对Activity的介绍:
49 4

热门文章

最新文章