版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、在Android系统中,一个Activity对应一个应用程序窗口,任何一个Activity的启动都是由AMS服务和应用程序进程相互配合来完成的。AMS服务统一调度系统中所有进程的Activity启动,而每个Activity的启动过程则由其所属进程来完成。AMS服务通过realStartActivityLocked函数来通知应用程序进程启动某个Activity:frameworks/base/services/java/com/android/server/am/ ActivityStack.javafinal boolean realStartActivityLocked(ActivityRe
2、cord r,ProcessRecord app, boolean andResume, boolean checkConfig)throws RemoteException ./系统参数发送变化,通知Activityif (checkConfig) Configuration config = mService.mWindowManager.updateOrientationFromAppTokens(mService.mConfiguration,r.mayFreezeScreenLocked(app) ? r.appToken : null);mService.updateConfigu
3、rationLocked(config, r, false, false);/将进程描述符设置到启动的Activity描述符中r.app = app;app.waitingToKill = null;/将启动的Activity添加到进程启动的Activity列表中int idx = app.activities.indexOf(r);if (idx < 0) app.activities.add(r);mService.updateLruProcessLocked(app, true, true);try ./通知应用程序进程加载Activityapp.thread.scheduleLa
4、unchActivity(new Intent(ent), r.appToken,System.identityHashCode(r), ,new Configuration(mService.mConfiguration),pat, r.icicle, results, newIntents, !andResume,mService.isNextTransitionForward(), profileFile, profileFd,profileAutoStop);. catch (RemoteException e) .if (mMainStack) mService
5、.startSetupActivityLocked();return true;AMS通过realStartActivityLocked函数来调度应用程序进程启动一个Activity,参数r为即将启动的Activity在AMS服务中的描述符,参数app为Activity运行所在的应用程序进程在AMS服务中的描述符。函数通过IApplicationThread代理对象ApplicationThreadProxy通知应用程序进程启动r对应的Activity,应用程序进程完成Activity的加载等准备工作后,AMS最后启动该Activity。启动Activity的创建等工作是在应用程序进程中完成的
6、,AMS是通过IApplicationThread接口和应用程序进程通信的。r.appToken 在AMS服务端的类型为Token,是IApplicationToken的Binder本地对象。frameworks/base/core/java/android/app/ ActivityThread.javapublic final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Configuration curConfig, CompatibilityInfo com
7、patInfo,Bundle state, List<ResultInfo> pendingResults,List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) /将AMS服务传过来的参数封装为ActivityClientRecord对象ActivityClientRecord r = new ActivityClientRecor
8、d();r.token = token;r.ident = ident;ent = intent;r.activityInfo = info;patInfo = compatInfo;r.state = state;r.pendingResults = pendingResults;r.pendingIntents = pendingNewIntents;r.startsNotResumed = notResumed;r.isForward = isForward;fileFile = profileName;fileFd = profileFd;r.autoSt
9、opProfiler = autoStopProfiler;updatePendingConfiguration(curConfig);/使用异步消息方式实现Activity的启动queueOrSendMessage(H.LAUNCH_ACTIVITY, r);参数token从AMS服务端经过Binder传输到应用程序进程后,变为IApplicationToken的Binder代理对象,类型为IApplicationToken.Proxy,这是因为AMS和应用程序运行在不同的进程中。通过queueOrSendMessage函数将Binder跨进程调用转换为应用程序进程中的异步消息处理frame
10、works/base/core/java/android/app/ ActivityThread.javaprivate class H extends Handler public void handleMessage(Message msg) switch (msg.what) case LAUNCH_ACTIVITY: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");ActivityClientRecord r = (ActivityClientRecord)msg.obj;r.p
11、ackageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, patInfo);handleLaunchActivity(r, null);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break;LAUNCH_ACTIVITY消息在应用程序主线程消息循环中得到处理,应用程序通过handleLaunchActivity函数来启动Activity。到此AMS服务就完成了Activity的调度任务,将Activity的启动过程完全交给了应用程序进程来完成。framework
12、s/base/core/java/android/app/ ActivityThread.javaprivate void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) /主线程空闲时会定时执行垃圾回收,主线程当前要完成启动Activity的任务,因此这里先暂停GCunscheduleGcIdler();if (fileFd != null) mProfiler.setProfiler(fileFile, fileFd);mProfiler.startProfiling();mP
13、rofiler.autoStopProfiler = r.autoStopProfiler;/ Make sure we are running with the most recent config.handleConfigurationChanged(null, null);/创建ActivityActivity a = performLaunchActivity(r, customIntent);if (a != null) r.createdConfig = new Configuration(mConfiguration);Bundle oldState = r.state;/启动A
14、ctivityhandleResumeActivity(r.token, false, r.isForward);.else.performLaunchActivity应用程序进程通过performLaunchActivity函数将即将要启动的Activity加载到当前进程空间来,同时为启动Activity做准备。frameworks/base/core/java/android/app/ ActivityThread.javaprivate Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent)
15、ActivityInfo aInfo = r.activityInfo;if (r.packageInfo = null) /通过Activity所在的应用程序信息及该Activity对应的CompatibilityInfo信息从PMS服务中查询当前Activity的包信息r.packageInfo = getPackageInfo(aInfo.applicationInfo, patInfo,Context.CONTEXT_INCLUDE_CODE);/获取当前Activity的组件信息ComponentName component = ent.getComponent();if
16、(component = null) component = ent.resolveActivity(mInitialApplication.getPackageManager();ent.setComponent(component);if (r.activityInfo.targetActivity != null) /packageName为启动Activity的包名,targetActivity为Activity的类名component = new ComponentName(r.activityInfo.packageName,r.activityInfo.tar
17、getActivity);/通过类反射方式加载即将启动的ActivityActivity activity = null;try java.lang.ClassLoader cl = r.packageInfo.getClassLoader();activity = mInstrumentation.newActivity(cl, component.getClassName(), ent);StrictMode.incrementExpectedActivityCount(activity.getClass();ent.setExtrasClassLoader(cl);i
18、f (r.state != null) r.state.setClassLoader(cl); catch (Exception e) .try /通过单例模式为应用程序进程创建Application对象Application app = r.packageInfo.makeApplication(false, mInstrumentation);if (activity != null) /为当前Activity创建上下文对象ContextImplContextImpl appContext = new ContextImpl();/上下文初始化appContext.init(r.packa
19、geInfo, r.token, this);appContext.setOuterContext(activity);CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager();.Configuration config = new Configuration(mCompatConfiguration);/将当前启动的Activity和上下文ContextImpl、Application绑定activity.attach(appContext, this, getInstrumentation(),
20、 r.token,r.ident, app, ent, r.activityInfo, title, r.parent,r.embeddedID, r.lastNonConfigurationInstances, config);./调用Activity的OnCreate函数mInstrumentation.callActivityOnCreate(activity, r.state);./将Activity保存到ActivityClientRecord中,ActivityClientRecord为Activity在应用程序进程中的描述符r.activity = activity;.
21、r.paused = true;/ActivityThread的成员变量mActivities保存了当前应用程序进程中的所有Activity的描述符mActivities.put(r.token, r); catch (SuperNotCalledException e) .return activity;在该函数中,首先通过PMS服务查找到即将启动的Activity的包名信息,然后通过类反射方式创建一个该Activity实例,同时为应用程序启动的每一个Activity创建一个LoadedApk实例对象,应用程序进程中创建的所有LoadedApk对象保存在ActivityThread的成员变量
22、mPackages中。接着通过LoadedApk对象的makeApplication函数,使用单例模式创建Application对象,因此在android应用程序进程中有且只有一个Application实例。然后为当前启动的Activity创建一个ContextImpl上下文对象,并初始化该上下文,到此我们可以知道,启动一个Activity需要以下对象:1) XXActivity对象,需要启动的Activity;2) LoadedApk对象,每个启动的Activity都拥有属
23、于自身的LoadedApk对象;3) ContextImpl对象,每个启动的Activity都拥有属于自身的ContextImpl对象;4) Application对象,应用程序进程中有且只有一个实例,和Activity是一对多的关系;加载Activity类public Activity newActivity(ClassLoader cl, String className,Intent intent)throws InstantiationException, Illeg
24、alAccessException,ClassNotFoundException return (Activity)cl.loadClass(className).newInstance();这里通过类反射的方式来加载要启动的Activity实例对象。LoadedApk构造过程首先介绍一下LoadedApk对象的构造过程:frameworks/base/core/java/android/app/ ActivityThread.javapublic final LoadedApk getPackageInfo(String packageName, CompatibilityInfo comp
25、atInfo,int flags) synchronized (mPackages) /通过Activity的包名从对应的成员变量中查找LoadedApk对象WeakReference<LoadedApk> ref;if (flags&Context.CONTEXT_INCLUDE_CODE) != 0) ref = mPackages.get(packageName); else ref = mResourcePackages.get(packageName);LoadedApk packageInfo = ref != null ? ref.get() : null;i
26、f (packageInfo != null && (packageInfo.mResources = null| packageInfo.mResources.getAssets().isUpToDate() .return packageInfo;/如果没有,则为当前Activity创建对应的LoadedApk对象ApplicationInfo ai = null;try /通过包名在PMS服务中查找应用程序信息ai = getPackageManager().getApplicationInfo(packageName,PackageManager.GET_SHARED_
27、LIBRARY_FILES, UserId.myUserId(); catch (RemoteException e) / Ignore/使用另一个重载函数创建LoadedApk对象if (ai != null) return getPackageInfo(ai, compatInfo, flags);return null;public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,int flags) boolean includeCode = (flags&Conte
28、xt.CONTEXT_INCLUDE_CODE) != 0;boolean securityViolation = includeCode && ai.uid != 0&& ai.uid != Process.SYSTEM_UID && (mBoundApplication != null? !UserId.isSameApp(ai.uid, mBoundApplication.appInfo.uid): true);if (flags&(Context.CONTEXT_INCLUDE_CODE|Context.CONTEXT_IGNOR
29、E_SECURITY)= Context.CONTEXT_INCLUDE_CODE) .return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode);private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,ClassLoader baseLoader, boolean securityViolation, boolean includeCode) /再次从对应的成员变量中查找LoadedApk
30、实例synchronized (mPackages) WeakReference<LoadedApk> ref;if (includeCode) ref = mPackages.get(aInfo.packageName); else ref = mResourcePackages.get(aInfo.packageName);LoadedApk packageInfo = ref != null ? ref.get() : null;if (packageInfo = null | (packageInfo.mResources != null&& !packag
31、eInfo.mResources.getAssets().isUpToDate() ./构造一个LoadedApk对象packageInfo =new LoadedApk(this, aInfo, compatInfo, this, baseLoader,securityViolation, includeCode &&(aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0);/保存LoadedApk实例到ActivityThread的相应成员变量中if (includeCode) mPackages.put(aInfo.pac
32、kageName,new WeakReference<LoadedApk>(packageInfo); else mResourcePackages.put(aInfo.packageName,new WeakReference<LoadedApk>(packageInfo);return packageInfo;frameworks/base/core/java/android/app/LoadedApk.javapublic LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo,Compatib
33、ilityInfo compatInfo,ActivityThread mainThread, ClassLoader baseLoader,boolean securityViolation, boolean includeCode) mActivityThread = activityThread;mApplicationInfo = aInfo;mPackageName = aInfo.packageName;mAppDir = aInfo.sourceDir;final int myUid = Process.myUid();mResDir = aInfo.uid = myUid ?
34、aInfo.sourceDir: aInfo.publicSourceDir;if (!UserId.isSameUser(aInfo.uid, myUid) && !Process.isIsolated() aInfo.dataDir = PackageManager.getDataDirForUser(UserId.getUserId(myUid),mPackageName);mSharedLibraries = aInfo.sharedLibraryFiles;mDataDir = aInfo.dataDir;mDataDirFile = mDataDir != null
35、 ? new File(mDataDir) : null;mLibDir = aInfo.nativeLibraryDir;mBaseClassLoader = baseLoader;mSecurityViolation = securityViolation;mIncludeCode = includeCode;mCompatibilityInfo.set(compatInfo);if (mAppDir = null) /为应用程序进程创建一个ContextImpl上下文if (ActivityThread.mSystemContext = null) ActivityThread.mSys
36、temContext =ContextImpl.createSystemContext(mainThread);ActivityThread.mSystemContext.getResources().updateConfiguration( mainThread.getConfiguration(), mainThread.getDisplayMetricsLocked(compatInfo, false), compatInfo);mClassLoader = ActivityThread.mSystemContext.getClassLoader();mResources = Activ
37、ityThread.mSystemContext.getResources();从以上LoadedApk的构造函数可以看出,LoadedApk类记录了Activity运行所在的ActivityThread、Activity所在的应用程序信息、Activity的包名、Activity的资源路径、Activity的库路径、Activity的数据存储路径、类加载器和应用程序所使用的资源等信息。Application构造过程当Activity为应用程序进程启动的第一个Activity,因此需要构造一个Application对象frameworks/base/core/java/android/app/
38、LoadedApk.javapublic Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) /在应用程序进程空间以单例模式创建Application对象if (mApplication != null) return mApplication;Application app = null;/得到应用程序的Application类名String appClass = mApplicationInfo.className;/如果应用程序没用重写Application,则
39、使用Android默认的Application类if (forceDefaultAppClass | (appClass = null) appClass = "android.app.Application"try java.lang.ClassLoader cl = getClassLoader();/为Application实例创建一个上下文对象ContextImplContextImpl appContext = new ContextImpl();/初始化上下文appContext.init(this, null, mActivityThread);/创建Appl
40、ication实例对象app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);appContext.setOuterContext(app); catch (Exception e) .mActivityThread.mAllApplications.add(app);mApplication = app;if (instrumentation != null) try /调用Application的OnCreate函数instrumentation.callApplicationOnCre
41、ate(app); catch (Exception e) .return app;在应用程序开发过程中,当我们重写了Application类后,应用程序加载运行的是我们定义的Application类,否则就加载运行默认的Application类。从Application对象的构造过程就可以解释为什么应用程序启动后首先执行的是Application的OnCreate函数。在实例化Application对象时,同样创建并初始化了一个ContextImpl上下文对象。ContextImpl构造过程前面我们介绍了,每一个Activity拥有一个上下文对象ContextImpl,每一个Applicat
42、ion对象也拥有一个ContextImpl上下文对象,那么ContextImpl对象又是如何构造的呢?frameworks/base/core/java/android/app/ ContextImpl.javaContextImpl() mOuterContext = this;ContextImpl的构造过程什么也没干,通过调用ContextImpl的init函数进行初始化final void init(LoadedApk packageInfo,IBinder activityToken, ActivityThread mainThread) init(packageInfo, acti
43、vityToken, mainThread, null, null);final void init(LoadedApk packageInfo,IBinder activityToken, ActivityThread mainThread,Resources container, String basePackageName) mPackageInfo = packageInfo;mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;mResources = mPack
44、ageInfo.getResources(mainThread);if (mResources != null && container != null&& container.getCompatibilityInfo().applicationScale !=mResources.getCompatibilityInfo().applicationScale) mResources = mainThread.getTopLevelResources(mPackageInfo.getResDir(), container.getCompatibilityInfo
45、();mMainThread = mainThread;mContentResolver = new ApplicationContentResolver(this, mainThread);setActivityToken(activityToken);从ContextImpl的初始化函数中可以知道,ContextImpl记录了应用程序的包名信息、应用程序的资源信息、应用程序的主线程、ContentResolver及Activity对应的IApplicationToken.Proxy,当然对应Application对象所拥有的ContextImpl上下文就没有对应的Token了。通过前面的分
46、析我们可以知道各个对象之间的关系:对象Attach过程Activity所需要的对象都创建好了,就需要将Activity和Application对象、ContextImpl对象绑定在一起。frameworks/base/core/java/android/app/ Activity.javafinal void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token,Application application, Intent intent, ActivityInfo info,
47、CharSequence title, Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances,Configuration config) attach(context, aThread, instr, token, 0, application, intent, info, title, parent, id,lastNonConfigurationInstances, config);context:Activity的上下文对象,就是前面创建的ContextImpl对象;aThr
48、ead:Activity运行所在的主线程描述符ActivityThread;instr:用于监控Activity运行状态的Instrumentation对象;token:用于和AMS服务通信的IApplicationToken.Proxy代理对象;application:Activity运行所在进程的Application对象;parent:启动当前Activity的Activity;final void attach(Context context, ActivityThread aThread,Instrumentation instr, IBinder token, int ident,
49、Application application, Intent intent, ActivityInfo info,CharSequence title, Activity parent, String id,NonConfigurationInstances lastNonConfigurationInstances,Configuration config) /将上下文对象ContextImpl保存到Activity的成员变量中attachBaseContext(context);/每个Activity都拥有一个FragmentManager,这里就是将当前Activity设置到Fragm
50、entManager中管理mFragments.attachActivity(this);/创建窗口对象mWindow = PolicyManager.makeNewWindow(this);mWindow.setCallback(this);mWindow.getLayoutInflater().setPrivateFactory(this);if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) mWindow.setSoftInputMode(info.softInputMode
51、);if (info.uiOptions != 0) mWindow.setUiOptions(info.uiOptions);/记录应用程序的UI线程mUiThread = Thread.currentThread();/记录应用程序的ActivityThread对象mMainThread = aThread;mInstrumentation = instr;mToken = token;mIdent = ident;mApplication = application;mIntent = intent;mComponent = intent.getComponent();mActivity
52、Info = info;mTitle = title;mParent = parent;mEmbeddedID = id;mLastNonConfigurationInstances = lastNonConfigurationInstances;/为Activity所在的窗口创建窗口管理器mWindow.setWindowManager(null, mToken, mComponent.flattenToString(),(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);if (mParent != null) m
53、Window.setContainer(mParent.getWindow();mWindowManager = mWindow.getWindowManager();mCurrentConfig = config;在该attach函数中主要做了以下几件事:1) 将Activity设置到FragmentManager中;2) 根据参数初始化Activity的成员变量;3)
54、; 为Activity创建窗口Window对象;4) 为Window创建窗口管理器;到此为止应用程序进程为启动的Activity对象创建了以下不同的实例对象,它们之间的关系如下:应用程序窗口创建过程frameworks/base/core/java/com/android/internal/policy/ PolicyManager.javapublic static Window makeNewWindow(Context context) return sPolicy.makeNew
55、Window(context);通过Policy类的makeNewWindow函数来创建一个应用程序窗口private static final String POLICY_IMPL_CLASS_NAME ="ernal.policy.impl.Policy"private static final IPolicy sPolicy;static try Class policyClass = Class.forName(POLICY_IMPL_CLASS_NAME);sPolicy = (IPolicy)policyClass.newInsta
56、nce(); catch (ClassNotFoundException ex) .frameworks/base/policy/src/com/android/internal/policy/impl/ Policy.javapublic Window makeNewWindow(Context context) return new PhoneWindow(context);应用程序窗口的创建过程其实就是构造一个PhoneWindow对象。PhoneWindow类是通过静态方式加载到应用程序进程空间的。private static final String preload_classes
57、= "ernal.policy.impl.PhoneLayoutInflater","ernal.policy.impl.PhoneWindow","ernal.policy.impl.PhoneWindow$1","ernal.policy.impl.PhoneWindow$ContextMenuCallback","ernal.policy.impl.PhoneWindow$DecorView","ernal.policy.impl.PhoneWindow$PanelFeatureState","ernal.policy.impl.PhoneWindow$PanelFeatureState$SavedState",;static for
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024-2030年中国万能铣床行业发展趋势及投资前景预测报告
- 2024-2030年中国一体化振动变送器行业市场深度分析及发展前景预测报告
- 2024-2030年中国高锰酸钾氧化淀粉胶粘剂行业市场供需现状及未来发展趋势报告
- 2024-2030年中国高速冲床行业发展趋势及投资前景预测报告
- 2024-2030年中国高端装备制造市场深度调查及投资方向研究报告
- 2024-2030年中国高炉气发电业未来趋势预测分析及投资规划研究建议报告
- 2024-2030年中国高岭土行业发展监测及投资战略研究报告
- 2024-2030年中国风帘机市场前景预测及投资规划研究报告
- 2024-2030年中国集装箱运输行业市场调研分析及投资战略咨询报告
- 2024-2030年中国阀门驱动装置行业市场全景评估及发展趋势研究预测报告
- 2024年北京市中考英语试卷真题(含答案)
- 2024年广东省初中学业水平考试生物押题卷
- JBT 8127-2011 内燃机 燃油加热器
- 国开《毛泽东思想和中国特色社会主义理论体系概论》2024春+试题A答案
- 2.2022-2023学年广东省深圳实验学校八年级(下)期末数学试卷
- 2024年公务员(国考)之行政职业能力测验真题及答案(必刷)
- MH-T 5012-2022民用机场目视助航设施施工质量验收规范
- 2024全权委托经营管理合同
- 办公综合楼施工组织设计
- 锥齿轮座加工工艺与工装设计
- 煤矿废弃物清运协议
评论
0/150
提交评论