博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Activity的启动流程分析
阅读量:5734 次
发布时间:2019-06-18

本文共 7808 字,大约阅读时间需要 26 分钟。

Activity启动分为很多种情况,这里说的是打开新的应用程序第一个Activity的流程。 

1. AcitivityManager产生新进程,新进程从android.app.ActivityThread.main开始运行。这里就是一般意义上的程序入口点,类似于C的main函数。

ActivityManagerService.java 

1  private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr) {2        // Process里面通知Zygote服务,Zygote真正产生新的进程(准确说是复制一个)4        int pid = Process.start("android.app.ActivityThread",6                     mSimpleProcessManagement ? app.processName : null, uid, uid,7   }

 2.ActivityThread的main函数中将Looper准备起来,prepareMainLooper标志着这是应用程序主线程的Looper对象。

ActivityThread.java  

1 public static final void main(String[] args) {2     Looper.prepareMainLooper();3     ActivityThread thread = new ActivityThread();4     thread.attach(false);5     // 这里闭合消息循环 6     Looper.loop();7 }

 3. 接下来调用attach,参数为false,表明这不是系统进程,是给普通应用程序用使用的进程。

ActivityThread.java   

1 private final void attach(boolean system) { 2              ViewRoot.addFirstDrawHandler(new Runnable() { 4                 public void run() { 5                     ensureJitEnabled(); 6                 } 7             }); 8             RuntimeInit.setApplicationObject(mAppThread.asBinder()); 9             IActivityManager mgr = ActivityManagerNative.getDefault();10             mgr.attachApplication(mAppThread);11     }

    mAppThread是ApplicationThread对象,是提供给ActivityManagerService控制ActivityThread的回调接口。

1 private final class ApplicationThread extends ApplicationThreadNative { 2  3   public final void schedulePauseActivity(IBinder token, boolean finished,boolean userLeaving, int  configChanges){ 4  5             queueOrSendMessage(finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY, 6                     token, (userLeaving ? 1 : 0),  configChanges); 7         } 8  9   public final void scheduleStopActivity(IBinder token, boolean showWindow, int configChanges) {10            queueOrSendMessage(showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,11                 token, 0, configChanges);12         }13 14   .........15 16 }

    ActivityManagerService要Pause当前Activity,就会调用schedulePauseActivity想本地的消息循环中加入一个H.PAUSE_ACTIVITY的消息,然后立即返回以避免ActivityManagerService的阻塞。

 4.现在又回到了ActivityManagerService中

ActivityManagerService.java   

1  // ActivityManagerService中XXXLocked函数才是真正干活的地方,XXX只是个套 2  3     public final void attachApplication(IApplicationThread thread) { 4         int callingPid = Binder.getCallingPid(); 5         attachApplicationLocked(thread, callingPid); 6     } 7  8   9 10     private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {11 12         // 这里取出对应该Pid的ProcessRecord对象,如果取不出来,你就等着out吧13 14         app = mPidsSelfLocked.get(pid)15 16         // 为ProcessRecord对象补充信息17 18         app.thread = thread;19         app.curAdj = app.setAdj = -100;20         app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;21         app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;22         app.forcingToForeground = null;23         app.foregroundServices = false;24         app.debugging = false;25         // 清除timeout监测 26         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);27 28  29 30         // 回调之前的ActivityThread,让它记住自己在ActivityManagerService中的相关信息,传这么大坨东西,真给力31 32         thread.bindApplication(processName, app.instrumentationInfo != null33                     ? app.instrumentationInfo : app.info, providers,34                     app.instrumentationClass, app.instrumentationProfileFile,35                     app.instrumentationArguments, app.instrumentationWatcher, testMode, 36                     isRestrictedBackupMode || !normalMode,37                     mConfiguration, getCommonServicesLocked());38 39        // topRunningActivityLocked的意思没看太明白40 41        HistoryRecord hr = topRunningActivityLocked(null);42 43        // 启动Activity44 45        realStartActivityLocked(hr, app, true, true);46 47     }48 49  50 51     private final boolean realStartActivityLocked(HistoryRecord r,52             ProcessRecord app, boolean andResume, boolean checkConfig){53 54         // 这里又跑到ActivityThread中去了55 56        app.thread.scheduleLaunchActivity(new Intent(r.intent), r, System.identityHashCode(r),57                     r.info, r.icicle, results, newIntents, !andResume, isNextTransitionForward());58 59     }60 61

 

5.ActivityThread开始调度用户的Activity启动了

ActivityThread.java

1 private final void handleLaunchActivity(ActivityRecord r, Intent customIntent) { 2        Activity a = performLaunchActivity(r, customIntent); 3  4        ...... 5  6 } 7  8 private final void performLaunchActivity(ActivityRecord r, Intent customIntent) { 9 10        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();11        // 产生Activity 12        activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);13 14        // 将新生的Activity与当前应用关联15 16        activity.attach(appContext, this, getInstrumentation(), r.token,17                        r.ident, app, r.intent, r.activityInfo, title, r.parent,18                         r.embeddedID, r.lastNonConfigurationInstance,19                         r.lastNonConfigurationChildInstances, config);20 21       .....22 23 }

 6.Acivity与当前App关联,直到这里,平时应用所见的Activity才真正被构建

Actiivty.java 

1 final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident, 2     Application application, Intent intent, ActivityInfo info,  CharSequence title, Activity parent, String id, 3     Object lastNonConfigurationInstance, HashMap
lastNonConfigurationChildInstances, 4 Configuration config) { 5 6 // 记录传入ContexImpl实例,这就是平时所见的Activity Context 7 attachBaseContext(context); 8 // 创建与Activity关联的Window,可以简单理解为显示窗口 9 mWindow = PolicyManager.makeNewWindow(this);10 11 mUiThread = Thread.currentThread();12 13 mMainThread = aThread;14 mInstrumentation = instr;15 mToken = token;16 mIdent = ident;17 mApplication = application;18 mIntent = intent;19 mComponent = intent.getComponent();20 mActivityInfo = info;21 mTitle = title;22 mParent = parent;23 mEmbeddedID = id;24 // 构建WindowManager的代理LocalWindowManager 25 mWindow.setWindowManager(null, mToken, mComponent.flattenToString());26 if (mParent != null) {27 // 难道说整个Activity栈中的Activity都有同一个Container 28 mWindow.setContainer(mParent.getWindow());29 }30 mWindowManager = mWindow.getWindowManager();31 32 }

 7.ActivityThread

ActivityThread.java

1 private final void performLaunchActivity(ActivityRecord r, Intent customIntent) { 2  3        ...... 4  5        // 回调Activity::onCreate 6  7        mInstrumentation.callActivityOnCreate(activity, r.state); 8  9         // 记录新产生的Activity 10        mActivities.put(r.token, r);11 12 }13 14 private final void handleLaunchActivity(ActivityRecord r, Intent customIntent) {15 16        ......17 18        handleResumeActivity(r.token, false, r.isForward);19 20 }21 22  final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {23 24        ActivityRecord r = performResumeActivity(token, clearHide);25 26  27 28 }29 30 public final ActivityRecord performResumeActivity(IBinder token, boolean clearHide) {31 32         if (r.pendingIntents != null) {33               deliverNewIntents(r, r.pendingIntents);34               r.pendingIntents = null;35        }36        if (r.pendingResults != null) {37               deliverResults(r, r.pendingResults);38               r.pendingResults = null;39        }40        //回调Activity::onResume 41        r.activity.performResume();42 43 }

      到这里,Activity从产生到初始化的过程就全部结束了。之后就是等待用户界面的消息,根据消息进行相应的处理。整个过程中,在ActivityManagerServer、ActivityThread的互相协作下构建出Activity,并在相应的时机回调Activity的相应接口,完成Activity的初始化。

转载于:https://www.cnblogs.com/mjblogs/p/3899335.html

你可能感兴趣的文章
linux下使用过的命令总结(未整理完)
查看>>
ES6的一些文章
查看>>
LeetCode 198, 213 House Robber
查看>>
New Year Permutation(Floyd+并查集)
查看>>
Qt编写输入法V2018超级终结版
查看>>
<context:component-scan>详解
查看>>
DS博客作业07--查找
查看>>
[JOI2017] サッカー (Soccer)
查看>>
Git 方法
查看>>
[Python] numpy.nonzero
查看>>
2016-11-29
查看>>
C#反射的坑
查看>>
css3 box-shadow阴影(外阴影与外发光)讲解
查看>>
时间助理 时之助
查看>>
nginx快速安装
查看>>
自定义转场动画
查看>>
英国征召前黑客组建“网络兵团”
查看>>
Silverlight 2.5D RPG游戏“.NET技术”技巧与特效处理:(十二)魔法系统
查看>>
[NPM] Run npm scripts in series
查看>>
vs2013修改书签(vs书签文件位置)
查看>>