activity详解(二 源码篇)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了activity详解(二 源码篇)相关的知识,希望对你有一定的参考价值。
想要剖析一个activity灵魂深处的秘密,必然要从“召唤”它的地方开始,一步一步跟踪到它结束,那么现在让我们在源码内一步一步了解他的整个生命周期吧
一般来说,我们打开一个activity的方式是使用startActivity方法来打开一个Activity类的子类,所以查看第一个方法
/** * Same as {@link #startActivity(Intent, Bundle)} with no options * specified. * 和startActivity(Intent, Bundle)方法相同,只不过没有定义Bundle * * @param intent The intent to start. * * @throws android.content.ActivityNotFoundException * * @see {@link #startActivity(Intent, Bundle)} * @see #startActivityForResult */ @Override public void startActivity(Intent intent) { this.startActivity(intent, null); }
这里我们可以知道,其实在传入一个intent参数之后startActivity方法后,其实它的内部又会调用一个不同参的startActivity的重载方法,那么继续查看这个方法
/** * Launch a new activity. You will not receive any information about when * the activity exits. This implementation overrides the base version, * providing information about * the activity performing the launch. Because of this additional * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not * required; if not specified, the new activity will be added to the * task of the caller. * 启动一个新的activity.而在该activity退出时,你将不会收到任何信息. * 它实现并重写了基础版本,提供activity准备启动时的信息, * 因为附加的启动flag没有被强制要求需要填写,如果没有设置的话,新的activity将会被加入到调用的task栈内. * (结合下文可知,启动flag,类似FLAG_ACTIVITY_NEW_TASK的,定义的是activity的启动方式,和activity的四种启动模式有关) * * <p>This method throws {@link android.content.ActivityNotFoundException} * if there was no Activity found to run the given Intent. * * @param intent The intent to start. * @param options Additional options for how the Activity should be started. * See {@link android.content.Context#startActivity(Intent, Bundle) * Context.startActivity(Intent, Bundle)} for more details. * * @throws android.content.ActivityNotFoundException * * @see {@link #startActivity(Intent)} * @see #startActivityForResult */ @Override public void startActivity(Intent intent, @Nullable Bundle options) { if (options != null) { startActivityForResult(intent, -1, options); } else { // Note we want to go through this call for compatibility with // applications that may have overridden the method. startActivityForResult(intent, -1); } }
可以看到因为使用startActivity(intent),我们一般调用的都会是startActivityForResult(intent, -1),那么startActivityForResult方法是什么呢
/** * Same as calling {@link #startActivityForResult(Intent, int, Bundle)} * with no options. * * @param intent The intent to start. * @param requestCode If >= 0, this code will be returned in * onActivityResult() when the activity exits. * requestCode如果大于1,那么在activity结束后,会在onActivityResult()方法中返回这个code值 * (默认传入的是-1,所以不会在activity结束后返回code值) * * @throws android.content.ActivityNotFoundException * * @see #startActivity */ public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) { startActivityForResult(intent, requestCode, null); }
得,又是一个重载方法
/** * Launch an activity for which you would like a result when it finished. * When this activity exits, your * onActivityResult() method will be called with the given requestCode. * Using a negative requestCode is the same as calling * {@link #startActivity} (the activity is not launched as a sub-activity). * * <p>Note that this method should only be used with Intent protocols * that are defined to return a result. In other protocols (such as * {@link Intent#ACTION_MAIN} or {@link Intent#ACTION_VIEW}), you may * not get the result when you expect. For example, if the activity you * are launching uses the singleTask launch mode, it will not run in your * task and thus you will immediately receive a cancel result. * * <p>As a special case, if you call startActivityForResult() with a requestCode * >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your * activity, then your window will not be displayed until a result is * returned back from the started activity. This is to avoid visible * flickering when redirecting to another activity. * * <p>This method throws {@link android.content.ActivityNotFoundException} * if there was no Activity found to run the given Intent. * * @param intent The intent to start. * @param requestCode If >= 0, this code will be returned in * onActivityResult() when the activity exits. * @param options Additional options for how the Activity should be started. * See {@link android.content.Context#startActivity(Intent, Bundle) * Context.startActivity(Intent, Bundle)} for more details. * * @throws android.content.ActivityNotFoundException * * @see #startActivity */ public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null) { Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options); if (ar != null) { mMainThread.sendActivityResult( mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData()); } if (requestCode >= 0) { // If this start is requesting a result, we can avoid making // the activity visible until the result is received. Setting // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the // activity hidden during this time, to avoid flickering. // This can only be done when a result is requested because // that guarantees we will get information back when the // activity is finished, no matter what happens to it. mStartedActivity = true; } cancelInputsAndStartExitTransition(options); // TODO Consider clearing/flushing other event sources and events for child windows. } else { if (options != null) { mParent.startActivityFromChild(this, intent, requestCode, options); } else { // Note we want to go through this method for compatibility with // existing applications that may have overridden it. mParent.startActivityFromChild(this, intent, requestCode); } } }
以上是关于activity详解(二 源码篇)的主要内容,如果未能解决你的问题,请参考以下文章
Android 启动过程Activity 启动源码分析 ( ActivityThread 流程分析 二 )
Android 启动过程Activity 启动源码分析 ( AMS -> ActivityThreadAMS 线程阶段 二 )
Android 逆向整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 | /bin/dexopt 源码分析 )(代码片段