Android应用程序启动过程源代码分析(4)

Android应用程序启动过程源代码分析(4)

         Step 28. ActivityStack.realStartActivityLocked

        这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:


  1. public class ActivityStack {   
  2.    
  3.     ……   
  4.    
  5.     final boolean realStartActivityLocked(ActivityRecord r,   
  6.             Proce***ecord app, boolean andResume, boolean checkConfig)   
  7.             throws RemoteException {   
  8.            
  9.         ……   
  10.    
  11.         r.app = app;   
  12.    
  13.         ……   
  14.    
  15.         int idx = app.activities.indexOf(r);   
  16.         if (idx < 0) {   
  17.             app.activities.add(r);   
  18.         }   
  19.            
  20.         ……   
  21.    
  22.         try {   
  23.             ……   
  24.    
  25.             List<ResultInfo> results = null;   
  26.             List<Intent> newIntents = null;   
  27.             if (andResume) {   
  28.                 results = r.results;   
  29.                 newIntents = r.newIntents;   
  30.             }   
  31.        
  32.             ……   
  33.                
  34.             app.thread.scheduleLaunchActivity(new Intent(r.intent), r,   
  35.                 System.identityHashCode(r),   
  36.                 r.info, r.icicle, results, newIntents, !andResume,   
  37.                 mService.isNextTransitionForward());   
  38.    
  39.             ……   
  40.    
  41.         } catch (RemoteException e) {   
  42.             ……   
  43.         }   
  44.    
  45.         ……   
  46.    
  47.         return true;   
  48.     }   
  49.    
  50.     ……   
  51.    
  52. }   

        这里最终通过app.thread进入到ApplicationThreadProxy的scheduleLaunchActivity函数中,注意,这里的第二个参数r,是一个ActivityRecord类型的Binder对象,用来作来这个Activity的token值。

        Step 29. ApplicationThreadProxy.scheduleLaunchActivity
        这个函数定义在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:


  1. class ApplicationThreadProxy implements IApplicationThread {   
  2.    
  3.     ……   
  4.    
  5.     public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,   
  6.             ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,   
  7.             List<Intent> pendingNewIntents, boolean notResumed, boolean isForward)   
  8.             throws RemoteException {   
  9.         Parcel data = Parcel.obtain();   
  10.         data.writeInterfaceToken(IApplicationThread.descriptor);   
  11.         intent.writeToParcel(data, 0);   
  12.         data.writeStrongBinder(token);   
  13.         data.writeInt(ident);   
  14.         info.writeToParcel(data, 0);   
  15.         data.writeBundle(state);   
  16.         data.writeTypedList(pendingResults);   
  17.         data.writeTypedList(pendingNewIntents);   
  18.         data.writeInt(notResumed ? 1 : 0);   
  19.         data.writeInt(isForward ? 1 : 0);   
  20.         mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,   
  21.             IBinder.FLAG_ONEWAY);   
  22.         data.recycle();   
  23.     }   
  24.    
  25.     ……   
  26.    
  27. }   

 

        这个函数最终通过Binder驱动程序进入到ApplicationThread的scheduleLaunchActivity函数中。

        Step 30. ApplicationThread.scheduleLaunchActivity
        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:


  1. public final class ActivityThread {   
  2.    
  3.     ……   
  4.    
  5.     private final class ApplicationThread extends ApplicationThreadNative {   
  6.    
  7.         ……   
  8.    
  9.         // we use token to identify this activity without having to send the   
  10.         // activity itself back to the activity manager. (matters more with ipc)   
  11.         public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,   
  12.                 ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,   
  13.                 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward) {   
  14.             ActivityClientRecord r = new ActivityClientRecord();   
  15.    
  16.             r.token = token;   
  17.             r.ident = ident;   
  18.             r.intent = intent;   
  19.             r.activityInfo = info;   
  20.             r.state = state;   
  21.    
  22.             r.pendingResults = pendingResults;   
  23.             r.pendingIntents = pendingNewIntents;   
  24.    
  25.             r.startsNotResumed = notResumed;   
  26.             r.isForward = isForward;   
  27.    
  28.             queueOrSendMessage(H.LAUNCH_ACTIVITY, r);   
  29.         }   
  30.    
  31.         ……   
  32.    
  33.     }   
  34.    
  35.     ……   
  36. }   

 

         函数首先创建一个ActivityClientRecord实例,并且初始化它的成员变量,然后调用ActivityThread类的queueOrSendMessage函数进一步处理。

         Step 31. ActivityThread.queueOrSendMessage
         这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:


  1. public final class ActivityThread {   
  2.    
  3.     ……   
  4.    
  5.     private final class ApplicationThread extends ApplicationThreadNative {   
  6.    
  7.         ……   
  8.    
  9.         // if the thread hasn’t started yet, we don’t have the handler, so just   
  10.         // save the messages until we’re ready.   
  11.         private final void queueOrSendMessage(int what, Object obj) {   
  12.             queueOrSendMessage(what, obj, 00);   
  13.         }   
  14.    
  15.         ……   
  16.    
  17.         private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {   
  18.             synchronized (this) {   
  19.                 ……   
  20.                 Message msg = Message.obtain();   
  21.                 msg.what = what;   
  22.                 msg.obj = obj;   
  23.                 msg.arg1 = arg1;   
  24.                 msg.arg2 = arg2;   
  25.                 mH.sendMessage(msg);   
  26.             }   
  27.         }   
  28.    
  29.         ……   
  30.    
  31.     }   
  32.    
  33.     ……   
  34. }   

 

        函数把消息内容放在msg中,然后通过mH把消息分发出去,这里的成员变量mH我们在前面已经见过,消息分发出去后,最后会调用H类的handleMessage函数。

        Step 32. H.handleMessage

        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:


  1. public final class ActivityThread {   
  2.    
  3.     ……   
  4.    
  5.     private final class H extends Handler {   
  6.    
  7.         ……   
  8.    
  9.         public void handleMessage(Message msg) {   
  10.             ……   
  11.             switch (msg.what) {   
  12.             case LAUNCH_ACTIVITY: {   
  13.                 ActivityClientRecord r = (ActivityClientRecord)msg.obj;   
  14.    
  15.                 r.packageInfo = getPackageInfoNoCheck(   
  16.                     r.activityInfo.applicationInfo);   
  17.                 handleLaunchActivity(r, null);   
  18.             } break;   
  19.             ……   
  20.             }   
  21.    
  22.         ……   
  23.    
  24.     }   
  25.    
  26.     ……   
  27. }   

 

       这里最后调用ActivityThread类的handleLaunchActivity函数进一步处理。

        Step 33. ActivityThread.handleLaunchActivity

        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:


  1. public final class ActivityThread {   
  2.    
  3.     ……   
  4.    
  5.     private final void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {   
  6.         ……   
  7.    
  8.         Activity a = performLaunchActivity(r, customIntent);   
  9.    
  10.         if (a != null) {   
  11.             r.createdConfig = new Configuration(mConfiguration);   
  12.             Bundle oldState = r.state;   
  13.             handleResumeActivity(r.token, false, r.isForward);   
  14.    
  15.             ……   
  16.         } else {   
  17.             ……   
  18.         }   
  19.     }   
  20.    
  21.     ……   
  22. }   

 

       这里首先调用performLaunchActivity函数来加载这个Activity类,即shy.luo.activity.MainActivity,然后调用它的onCreate函数,最后回到handleLaunchActivity函数时,再调用handleResumeActivity函数来使这个Activity进入Resumed状态,即会调用这个Activity的onResume函数,这是遵循Activity的生命周期的。

        Step 34. ActivityThread.performLaunchActivity
        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:


  1. public final class ActivityThread {   
  2.    
  3.     ……   
  4.    
  5.     private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {   
  6.            
  7.         ActivityInfo aInfo = r.activityInfo;   
  8.         if (r.packageInfo == null) {   
  9.             r.packageInfo = getPackageInfo(aInfo.applicationInfo,   
  10.                 Context.CONTEXT_INCLUDE_CODE);   
  11.         }   
  12.    
  13.         ComponentName component = r.intent.getComponent();   
  14.         if (component == null) {   
  15.             component = r.intent.resolveActivity(   
  16.                 mInitialApplication.getPackageManager());   
  17.             r.intent.setComponent(component);   
  18.         }   
  19.    
  20.         if (r.activityInfo.targetActivity != null) {   
  21.             component = new ComponentName(r.activityInfo.packageName,   
  22.                 r.activityInfo.targetActivity);   
  23.         }   
  24.    
  25.         Activity activity = null;   
  26.         try {   
  27.             java.lang.ClassLoader cl = r.packageInfo.getClassLoader();   
  28.             activity = mInstrumentation.newActivity(   
  29.                 cl, component.getClassName(), r.intent);   
  30.             r.intent.setExtrasClassLoader(cl);   
  31.             if (r.state != null) {   
  32.                 r.state.setClassLoader(cl);   
  33.             }   
  34.         } catch (Exception e) {   
  35.             ……   
  36.         }   
  37.    
  38.         try {   
  39.             Application app = r.packageInfo.makeApplication(false, mInstrumentation);   
  40.    
  41.             ……   
  42.    
  43.             if (activity != null) {   
  44.                 ContextImpl appContext = new ContextImpl();   
  45.                 appContext.init(r.packageInfo, r.token, this);   
  46.                 appContext.setOuterContext(activity);   
  47.                 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());   
  48.                 Configuration config = new Configuration(mConfiguration);   
  49.                 ……   
  50.                 activity.attach(appContext, this, getInstrumentation(), r.token,   
  51.                     r.ident, app, r.intent, r.activityInfo, title, r.parent,   
  52.                     r.embeddedID, r.lastNonConfigurationInstance,   
  53.                     r.lastNonConfigurationChildInstances, config);   
  54.    
  55.                 if (customIntent != null) {   
  56.                     activity.mIntent = customIntent;   
  57.                 }   
  58.                 r.lastNonConfigurationInstance = null;   
  59.                 r.lastNonConfigurationChildInstances = null;   
  60.                 activity.mStartedActivity = false;   
  61.                 int theme = r.activityInfo.getThemeResource();   
  62.                 if (theme != 0) {   
  63.                     activity.setTheme(theme);   
  64.                 }   
  65.    
  66.                 activity.mCalled = false;   
  67.                 mInstrumentation.callActivityOnCreate(activity, r.state);   
  68.                 ……   
  69.                 r.activity = activity;   
  70.                 r.stopped = true;   
  71.                 if (!r.activity.mFinished) {   
  72.                     activity.performStart();   
  73.                     r.stopped = false;   
  74.                 }   
  75.                 if (!r.activity.mFinished) {   
  76.                     if (r.state != null) {   
  77.                         mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);   
  78.                     }   
  79.                 }   
  80.                 if (!r.activity.mFinished) {   
  81.                     activity.mCalled = false;   
  82.                     mInstrumentation.callActivityOnPostCreate(activity, r.state);   
  83.                     if (!activity.mCalled) {   
  84.                         throw new SuperNotCalledException(   
  85.                             “Activity “ + r.intent.getComponent().toShortString() +   
  86.                             ” did not call through to super.onPostCreate()”);   
  87.                     }   
  88.                 }   
  89.             }   
  90.             r.paused = true;   
  91.    
  92.             mActivities.put(r.token, r);   
  93.    
  94.         } catch (SuperNotCalledException e) {   
  95.             ……   
  96.    
  97.         } catch (Exception e) {   
  98.             ……   
  99.         }   
  100.    
  101.         return activity;   
  102.     }   
  103.    
  104.     ……   
  105. }   

 

       函数前面是收集要启动的Activity的相关信息,主要package和component信息:


  1. ActivityInfo aInfo = r.activityInfo;   
  2. if (r.packageInfo == null) {   
  3.      r.packageInfo = getPackageInfo(aInfo.applicationInfo,   
  4.              Context.CONTEXT_INCLUDE_CODE);   
  5. }   
  6.    
  7. ComponentName component = r.intent.getComponent();   
  8. if (component == null) {   
  9.     component = r.intent.resolveActivity(   
  10.         mInitialApplication.getPackageManager());   
  11.     r.intent.setComponent(component);   
  12. }   
  13.    
  14. if (r.activityInfo.targetActivity != null) {   
  15.     component = new ComponentName(r.activityInfo.packageName,   
  16.             r.activityInfo.targetActivity);   
  17. }   

     然后通过ClassLoader将shy.luo.activity.MainActivity类加载进来:


  1.   Activity activity = null;   
  2.   try {   
  3. java.lang.ClassLoader cl = r.packageInfo.getClassLoader();   
  4. activity = mInstrumentation.newActivity(   
  5.     cl, component.getClassName(), r.intent);   
  6. r.intent.setExtrasClassLoader(cl);   
  7. if (r.state != null) {   
  8.     r.state.setClassLoader(cl);   
  9. }   
  10.   } catch (Exception e) {   
  11. ……   
  12.   }   

   接下来是创建Application对象,这是根据AndroidManifest.xml配置文件中的Application标签的信息来创建的:


  1. Application app = r.packageInfo.makeApplication(false, mInstrumentation);   

 后面的代码主要创建Activity的上下文信息,并通过attach方法将这些上下文信息设置到MainActivity中去:


  1.   activity.attach(appContext, this, getInstrumentation(), r.token,   
  2. r.ident, app, r.intent, r.activityInfo, title, r.parent,   
  3. r.embeddedID, r.lastNonConfigurationInstance,   
  4. r.lastNonConfigurationChildInstances, config);   

      最后还要调用MainActivity的onCreate函数:


  1. mInstrumentation.callActivityOnCreate(activity, r.state);   

      这里不是直接调用MainActivity的onCreate函数,而是通过mInstrumentation的callActivityOnCreate函数来间接调用,前面我们说过,mInstrumentation在这里的作用是监控Activity与系统的交互操作,相当于是系统运行日志。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/110569.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • mysql数据库关键字及用法_mysql唯一索引关键字

    mysql数据库关键字及用法_mysql唯一索引关键字利用mysqlexplain来对sql语句进行优化,你需要懂这些关键字各表示的含义,这样优化才有的放矢。

    2022年10月17日
  • Hashcode的作用_冻干粉的作用与功效

    Hashcode的作用_冻干粉的作用与功效title:HashCode作用以及使用date:2019-02-2003:33:00tags:SpringBootcategory:SpringBootdescription:HashCode作用以及使用前言博主github博主个人博客http://blog.healerjean.com感谢大神1、一些常见的HashCode1.1、Integer…

  • pycharm缩进快捷方法「建议收藏」

    pycharm缩进快捷方法「建议收藏」整体缩进:鼠标拉选住代码块,按下tab键。反向缩进:鼠标拉选住代码块,按下shift+tab键

    2022年10月24日
  • 宝塔搭建php项目是什么_用宝塔怎么修改网站源码

    宝塔搭建php项目是什么_用宝塔怎么修改网站源码宝塔搭建PHP项目宝塔下载地址我选的是linux用宝塔搭建前提是你买的服务器并没有安装任何的镜像与环境进入官网选择你要的然后点击立即安装进入安装教程安装要求根据自己的主机商进入,我的是阿里云的设置一些开放端口添加安全组规则添加这些必要的端口mysql3306的记住一定要放行,这样可用本地工具连接远程服务器的数据库上面设置好之后就可以安装了,我的是Centosyuminstall-ywget&&wget-Oin

  • XGBOOST + LR 模型融合 python 代码

    XGBOOST + LR 模型融合 python 代码XGBOOST+LR(XGBOOSTgridsearch)先留个广告,最近做一个数据挖掘的比赛,主要用的就是xgboost,等比赛完后年前好好整理代码开源,到时候代码会比下面整份完整。XGBOOST+LR是CTR常用的一种方式。下面是实现XGBOOST+LR的代码,具体的原理不做细说。有了下面的代码框架,你可以对xgboost进行参数优化搜索,同时可以利用

    2022年10月13日
  • 内网IP地址段_专用内网ip

    内网IP地址段_专用内网iptcp/ip协议中,专门保留了三个IP地址区域作为私有地址,其地址范围如下:10.0.0.0/8:10.0.0.0~10.255.255.255172.16.0.0/12:172.16.0.0~172.31.255.255192.168.0.0/16:192.168.0.0~192.168.255.255

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号