从应用启动看Activity的创建过程
2019独角兽企业重金招聘Python工程师标准>>>
本篇暂未完成。
/*
*Acitivity的创建过程:
*应用程序的入口为ActivityThread的main函数。
*在main函数中:
*/
public static void main(String[] args) {
SamplingProfilerIntegration.start();
// CloseGuard defaults to true and can be quite spammy. We// disable it here, but selectively enable it later (via// StrictMode) on debug builds, but using DropBox, not logs.CloseGuard.setEnabled(false);//为当前的User初始化一个用户目录,以及一些环境变量Environment.initForCurrentUser();// Set the reporter for event logging in libcoreEventLogger.setReporter(new EventLoggingReporter());Security.addProvider(new AndroidKeyStoreProvider());// Make sure TrustedCertificateStore looks in the right place for CA certificatesfinal File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());TrustedCertificateStore.setDefaultUserDirectory(configDir);Process.setArgV0("<pre-initialized>");Looper.prepareMainLooper();//创建了一个AcitivityThread,ActivityThread thread = new ActivityThread();thread.attach(false);if (sMainThreadHandler == null) {sMainThreadHandler = thread.getHandler();}AsyncTask.init();if (false) {Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, "ActivityThread"));}Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");}
private void attach(boolean system) {//将当前的ActivityThread对象赋值给ActivityThread的静态变量sCurrentActivityThreadsCurrentActivityThread = this;mSystemThread = system;//system=falseif (!system) {ViewRootImpl.addFirstDrawHandler(new Runnable() {@Overridepublic void run() {ensureJitEnabled();}});android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",UserHandle.myUserId());RuntimeInit.setApplicationObject(mAppThread.asBinder());//ActivityManagerNative属于IPC代理类,IPC服务端是ActivityManagerServicefinal IActivityManager mgr = ActivityManagerNative.getDefault();try {/*IPC调用attachApplication,aAppThread是ApplicationThread类型。 ApplicationThread继承于ApplicationThreadNative,ApplicationThreadNative继承于Binder。 Application创建之前的一些工作 */mgr.attachApplication(mAppThread);} catch (RemoteException ex) {// Ignore}// 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 {mgr.releaseSomeActivities(mAppThread);} catch (RemoteException e) {}}}});} else {//由于system为false,所以此处不执行android.ddm.DdmHandleAppName.setAppName("system_process",UserHandle.myUserId());try {//接下来是创建ContextImpl,Application,调用Application的onCreatemInstrumentation = new Instrumentation();ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);mInitialApplication = context.mPackageInfo.makeApplication(true, null);mInitialApplication.onCreate();} catch (Exception e) {throw new RuntimeException("Unable to instantiate Application():" + e.toString(), e);}}// add dropbox logging to libcoreDropBox.setReporter(new DropBoxReporter());ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {@Overridepublic void onConfigurationChanged(Configuration newConfig) {synchronized (mResourcesManager) {// We need to apply this change to the resources// immediately, because upon returning the view// hierarchy will be informed about it.if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {// This actually changed the resources! Tell// everyone about it.if (mPendingConfiguration == null ||mPendingConfiguration.isOtherSeqNewer(newConfig)) {mPendingConfiguration = newConfig;sendMessage(H.CONFIGURATION_CHANGED, newConfig);}}}}@Overridepublic void onLowMemory() {}@Overridepublic void onTrimMemory(int level) {}});}//在ActivityManagerService.java中:@Overridepublic final void attachApplication(IApplicationThread thread) {synchronized (this) {int callingPid = Binder.getCallingPid();final long origId = Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid);Binder.restoreCallingIdentity(origId);}}private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {// Find the application record that is being attached... either via// the pid if we are running in multiple processes, or just pull the// next app record if we are emulating process with anonymous threads.ProcessRecord app;if (pid != MY_PID && pid >= 0) {synchronized (mPidsSelfLocked) {app = mPidsSelfLocked.get(pid);}} else {app = null;}if (app == null) {Slog.w(TAG, "No pending application record for pid " + pid+ " (IApplicationThread " + thread + "); dropping process");EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);if (pid > 0 && pid != MY_PID) {Process.killProcessQuiet(pid);//TODO: Process.killProcessGroup(app.info.uid, pid);} else {try {thread.scheduleExit();} catch (Exception e) {// Ignore exceptions.}}return false;}//此处省去部分代码......boolean badApp = false;boolean didSomething = false;// See if the top visible activity is waiting to run in this process...if (normalMode) {try {if (mStackSupervisor.attachApplicationLocked(app)) {didSomething = true;}} catch (Exception e) {Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);badApp = true;}}//此处省去部分代码......return true;}boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {final String processName = app.processName;boolean didSomething = false;for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {final ActivityStack stack = stacks.get(stackNdx);if (!isFrontStack(stack)) {continue;}ActivityRecord hr = stack.topRunningActivityLocked(null);if (hr != null) {if (hr.app == null && app.uid == hr.info.applicationInfo.uid&& processName.equals(hr.processName)) {try {if (realStartActivityLocked(hr, app, true, true)) {didSomething = true;}} catch (RemoteException e) {Slog.w(TAG, "Exception in new application when starting activity "+ hr.intent.getComponent().flattenToShortString(), e);throw e;}}}}}if (!didSomething) {ensureActivitiesVisibleLocked(null, 0);}return didSomething;}final boolean realStartActivityLocked(ActivityRecord r,ProcessRecord app, boolean andResume, boolean checkConfig)throws RemoteException {r.startFreezingScreenLocked(app, 0);if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");mWindowManager.setAppVisibility(r.appToken, true);......//在此处通过IPC方式调用了ActivityThread的scheduleLaunchActivity,//scheduleLaunchActivity方法向主线程消息队列中发送了一个LAUNCH_ACTIVITY的消息。app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),r.compat, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState,results, newIntents, !andResume, mService.isNextTransitionForward(),profilerInfo);//此处省去部分代码......return true;}//到此在ActivityThread.java.attch()中的mgr.attachApplication(mAppThread);这句代码就执行完了。//attach方法执行完后,ActivityThread的Handler就去执行LAUNCH_ACTIVITY的消息了。也就是执行handleLaunchActivity().private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {// If we are getting ready to gc after going to the background, well// we are back active so skip it.unscheduleGcIdler();mSomeActivitiesChanged = true;//此处省去部分代码......//此处终于创建了AcitivityActivity a = performLaunchActivity(r, customIntent);if (a != null) {r.createdConfig = new Configuration(mConfiguration);Bundle oldState = r.state;handleResumeActivity(r.token, false, r.isForward,!r.activity.mFinished && !r.startsNotResumed);//此处省去部分代码.....} else {// If there was an error, for any reason, tell the activity// manager to stop us.try {ActivityManagerNative.getDefault().finishActivity(r.token, Activity.RESULT_CANCELED, null, false);} catch (RemoteException ex) {// Ignore}}}//这里有两个重要的方法。//1.performLaunchActivity。//2.handleResumeActivityprivate Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");ActivityInfo aInfo = r.activityInfo;if (r.packageInfo == null) {r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,Context.CONTEXT_INCLUDE_CODE);}ComponentName component = r.intent.getComponent();if (component == null) {component = r.intent.resolveActivity(mInitialApplication.getPackageManager());r.intent.setComponent(component);}if (r.activityInfo.targetActivity != null) {component = new ComponentName(r.activityInfo.packageName,r.activityInfo.targetActivity);}Activity activity = null;try {java.lang.ClassLoader cl = r.packageInfo.getClassLoader();//此处创建了Activity对象activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);StrictMode.incrementExpectedActivityCount(activity.getClass());r.intent.setExtrasClassLoader(cl);r.intent.prepareToEnterProcess();if (r.state != null) {r.state.setClassLoader(cl);}} catch (Exception e) {if (!mInstrumentation.onException(activity, e)) {throw new RuntimeException("Unable to instantiate activity " + component+ ": " + e.toString(), e);}}try {//创建Application对象Application app = r.packageInfo.makeApplication(false, mInstrumentation);if (activity != null) {Context appContext = createBaseContextForActivity(r, activity);CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());Configuration config = new Configuration(mCompatConfiguration);activity.attach(appContext, this, getInstrumentation(), r.token,r.ident, app, r.intent, r.activityInfo, title, r.parent,r.embeddedID, r.lastNonConfigurationInstances, config,r.voiceInteractor);if (customIntent != null) {activity.mIntent = customIntent;}r.lastNonConfigurationInstances = null;activity.mStartedActivity = false;//在此设置activity的主题int theme = r.activityInfo.getThemeResource();if (theme != 0) {activity.setTheme(theme);}activity.mCalled = false;//调用Activity的onCreate方法if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);} else {mInstrumentation.callActivityOnCreate(activity, r.state);}if (!activity.mCalled) {throw new SuperNotCalledException("Activity " + r.intent.getComponent().toShortString() +" did not call through to super.onCreate()");}r.activity = activity;r.stopped = true;//调用activity的onStart方法if (!r.activity.mFinished) {activity.performStart();r.stopped = false;}//调用activity的OnRestoreInstanceState方法if (!r.activity.mFinished) {if (r.isPersistable()) {if (r.state != null || r.persistentState != null) {mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,r.persistentState);}} else if (r.state != null) {mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);}}//调用activity的onPostCreate方法if (!r.activity.mFinished) {activity.mCalled = false;if (r.isPersistable()) {mInstrumentation.callActivityOnPostCreate(activity, r.state,r.persistentState);} else {mInstrumentation.callActivityOnPostCreate(activity, r.state);}if (!activity.mCalled) {throw new SuperNotCalledException("Activity " + r.intent.getComponent().toShortString() +" did not call through to super.onPostCreate()");}}}r.paused = true;mActivities.put(r.token, r);} catch (SuperNotCalledException e) {throw e;} catch (Exception e) {if (!mInstrumentation.onException(activity, e)) {throw new RuntimeException("Unable to start activity " + component+ ": " + e.toString(), e);}}return activity;}//调用了mInstrumentation.newActivity去创建Activity。//之后,调用了Activity的attach方法,在其中创建了window,设置了windowManager,public Activity newActivity(ClassLoader cl, String className,Intent intent)throws InstantiationException, IllegalAccessException,ClassNotFoundException {return (Activity)cl.loadClass(className).newInstance();}//newActivity方法很简单,通过反射创建Activity。//看完了performLaunchActivity。就进入另一个重要的方法handleResumeActivityfinal void handleResumeActivity(IBinder token,boolean clearHide, boolean isForward, boolean reallyResume) {// If we are getting ready to gc after going to the background, well// we are back active so skip it.unscheduleGcIdler();mSomeActivitiesChanged = true;// TODO Push resumeArgs into the activity for considerationActivityClientRecord r = performResumeActivity(token, clearHide);if (r != null) {final Activity a = r.activity;if (localLOGV) Slog.v(TAG, "Resume " + r + " started activity: " +a.mStartedActivity + ", hideForNow: " + r.hideForNow+ ", finished: " + a.mFinished);final int forwardBit = isForward ?WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;// If the window hasn't yet been added to the window manager,// and this guy didn't finish itself or start another activity,// then go ahead and add the window.boolean willBeVisible = !a.mStartedActivity;if (!willBeVisible) {try {willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(a.getActivityToken());} catch (RemoteException e) {}}if (r.window == null && !a.mFinished && willBeVisible) {r.window = r.activity.getWindow();View decor = r.window.getDecorView();decor.setVisibility(View.INVISIBLE);ViewManager wm = a.getWindowManager();WindowManager.LayoutParams l = r.window.getAttributes();a.mDecor = decor;l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;l.softInputMode |= forwardBit;if (a.mVisibleFromClient) {a.mWindowAdded = true;wm.addView(decor, l);}// If the window has already been added, but during resume// we started another activity, then don't yet make the// window visible.} else if (!willBeVisible) {if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");r.hideForNow = true;}// Get rid of anything left hanging around.cleanUpPendingRemoveWindows(r);// The window is now visible if it has been added, we are not// simply finishing, and we are not starting another activity.if (!r.activity.mFinished && willBeVisible&& r.activity.mDecor != null && !r.hideForNow) {if (r.newConfig != null) {if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "+ r.activityInfo.name + " with newConfig " + r.newConfig);performConfigurationChanged(r.activity, r.newConfig);freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));r.newConfig = null;}if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="+ isForward);WindowManager.LayoutParams l = r.window.getAttributes();if ((l.softInputMode& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)!= forwardBit) {l.softInputMode = (l.softInputMode& (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))| forwardBit;if (r.activity.mVisibleFromClient) {ViewManager wm = a.getWindowManager();View decor = r.window.getDecorView();wm.updateViewLayout(decor, l);}}r.activity.mVisibleFromServer = true;mNumVisibleActivities++;if (r.activity.mVisibleFromClient) {r.activity.makeVisible();}}if (!r.onlyLocalRequest) {r.nextIdle = mNewActivities;mNewActivities = r;if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);Looper.myQueue().addIdleHandler(new Idler());}r.onlyLocalRequest = false;// Tell the activity manager we have resumed.if (reallyResume) {try {ActivityManagerNative.getDefault().activityResumed(token);} catch (RemoteException ex) {}}} else {// If an exception was thrown when trying to resume, then// just end this activity.try {ActivityManagerNative.getDefault().finishActivity(token, Activity.RESULT_CANCELED, null, false);} catch (RemoteException ex) {}}}//先看看performResumeActivity方法。在此方法中调用activity的生命周期函数onResume。public final ActivityClientRecord performResumeActivity(IBinder token,boolean clearHide) {ActivityClientRecord r = mActivities.get(token);if (localLOGV) Slog.v(TAG, "Performing resume of " + r+ " finished=" + r.activity.mFinished);if (r != null && !r.activity.mFinished) {if (clearHide) {r.hideForNow = false;r.activity.mStartedActivity = false;}try {r.activity.mFragments.noteStateNotSaved();if (r.pendingIntents != null) {deliverNewIntents(r, r.pendingIntents);r.pendingIntents = null;}if (r.pendingResults != null) {deliverResults(r, r.pendingResults);r.pendingResults = null;}//调用onResume方法r.activity.performResume();EventLog.writeEvent(LOG_ON_RESUME_CALLED,UserHandle.myUserId(), r.activity.getComponentName().getClassName());r.paused = false;r.stopped = false;r.state = null;r.persistentState = null;} catch (Exception e) {if (!mInstrumentation.onException(r.activity, e)) {throw new RuntimeException("Unable to resume activity "+ r.intent.getComponent().toShortString()+ ": " + e.toString(), e);}}}return r;}//然后重点就是下面这段代码:if (r.window == null && !a.mFinished && willBeVisible) {//先拿到window和windowManager对象,这两个对象在上面介绍的Activity的attch方法中创建。r.window = r.activity.getWindow();View decor = r.window.getDecorView();decor.setVisibility(View.INVISIBLE);ViewManager wm = a.getWindowManager();WindowManager.LayoutParams l = r.window.getAttributes();a.mDecor = decor;l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;l.softInputMode |= forwardBit;if (a.mVisibleFromClient) {a.mWindowAdded = true;//windowManager显示decorView,此方法wm.addView(decor, l);}// If the window has already been added, but during resume// we started another activity, then don't yet make the// window visible.} else if (!willBeVisible) {if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");r.hideForNow = true;}
做个备注:
在ActivityThread.java中:
H是Handler的字类。负责处理Activity的各种操作。
performLaunchActivity中创建了Activity
LoadApk中存储了ActivityThread的引用,还有其他的一些关于该应用的目录等变量。
CompatibilityInfo类保存了应用程序运行的兼容性模式的信息
我们平时在Activity中使用的ContentResolver是ApplicationContentResolver类型的
转载于:https://my.oschina.net/KobeGong/blog/469051
从应用启动看Activity的创建过程相关推荐
- Activtiy完全解析(一、Activity的创建过程)
版权声明:本文为openXu原创文章[openXu的博客],未经博主允许不得以任何形式转载 在Android开发过程中,我们几乎每天都在跟Activity打交道.我们循规蹈矩的调用startAct ...
- Android提升篇系列:Activity recreate(Activity 重新创建/自我恢复)机制(一)
注:本文中的recreate是指当内存不足时,Activity被回收,但再次来到此Activity时,系统重新恢复的过程. 例如:当Activity A到Activity B时,如果内存不足,A被回收 ...
- 深入浅出Spring Security(二):FilterChainProxy的创建过程
上篇回顾 框架的核心是一个过滤器,这个过滤器名字叫springSecurityFilterChain,类型是FilterChainProxy WebSecurity和HttpSecurity都是建造者 ...
- Android Service启动到Activity
飞哥语录:心怀希望,就会充满力量! 从Service启动到Activity基本可以分为两类: 1.从自己应用的Service启动自己应用的Activity,即显式意图: 2.从自己应用的Service ...
- Java JVM 从虚拟机的角度看对象的创建与访问
专栏原创出处:github-源笔记文件 ,github-源码 ,欢迎 Star,转载请附上原文出处链接和本声明. Java JVM-虚拟机专栏系列笔记,系统性学习可访问个人复盘笔记-技术博客 Java ...
- activity启动流程_以AMS视角看Activity启动过程
原文作者:Levi_wayne 原文地址:blog.csdn.net/u012551754/article/details/78822782 特别声明:本文转载自网络,版权归作者所有,如有侵权请联系删 ...
- Android Activity的启动流程分析:以Launcher启动一个Activity为例,分析应用进程的创建、Activity的启动,以及他们和AMS之间的交互
文章目录 一. Step1 - Step 11:Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity: Step 1. Laun ...
- 【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )
Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...
- android启动activity的详细过程
首先认识几个重要的概念: ActivityManagerService: 四大组件管理的核心类,同时管理和调度用户进程 ActivityRecord: 在AMS中用来保存一个activity的信息 T ...
最新文章
- android适配不同分辨率的手机
- java的流对象和一些方法
- python 全局变量、局部变量
- 阿里开源首个深度学习框架 X-Deep Learning!
- Sqoop 使用指南
- linux一键安装aria2,Centos7下安装Aria2教程 之 Aria2 一键安装管理脚本
- 如何搭建自己的CI/CD平台:Gitlab+Jenkins+Docker+Harbor+K8s集群搭建CICD平台(持续集成部署Hexo博客Demo)
- 采集新闻数据的10个经典方法
- CocosCreator角色动态更换武器实现
- java浪漫之心代码_浪漫桃心的Android表白程序
- 微信支付消费者投诉消息推送接入企业微信群
- 转:一个情绪稳定的人背后,都是高情商和大格局
- 该怎么回答面试官问“你有什么优缺点?”
- 学习单片机的几点经验之谈
- Win10 清理备用内存
- ECS弹性云服务器常用端口、安全组
- Java Swing实用小工具开发
- linux下编辑VI窗口插入与编辑命令
- 面试归来——梳理社招面试以及浅述对程序员职业生涯的看法
- 尚硅谷大数据开发Day02