AMS与Activity的交互
来源:互联网 发布:org.apache.tiles 编辑:程序博客网 时间:2024/05/16 07:14
上面是Activity典型的生命周期流程图,基本的就不讲了,提两个问题来求解下
1:当启动一个新的Activity时,新旧两个Activity的生命周期执行顺序
2:当你在onCreat中调用startActivity或者finish的时候,生命周期执行流程
首先来求解第一个问题,很简单,建立两个Activity,每个生命周期上打上log
@Overrideprotected void onStart() { Log.e("xw", "111---onStart"); super.onStart();}@Overrideprotected void onStart() { Log.e("xw", "222---onStart"); super.onStart();}
跳转之后log为
可以看到首先调用了第一个Activity的onPause方法,之后第二个Activity的onCreat,onStart,onResume方法依次执行,最后才轮到第一个Activity的onStop方法。
先不从实现单从产品的角度来讲,这种执行顺序很有道理,因为onPause执行后意味着Activity不再接收事件,所以onPause必定要在第二个Activity的onResume方法之前执行,否则会导致有两个Activity可以接收事件,这显然不合理。而各种系统都要考虑的就是响应速度,从安卓来讲,就是要最快的展示给用户新的Activity,也就是新的Activity的生命周期要尽早执行,所以,最终结论是,首先终止第一个Activity接收事件的能力,之后展现新的Activity,最后第一个Activity再去进行收尾工作。具体的实现等下再说。
接着是第二个问题,首先看调用startActivity
@Override protected void onCreate(Bundle savedInstanceState) { Log.e("xw", "111---onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startActivity(new Intent(MainActivity.this, Main2Activity.class)); }
打印的log为
可以看到完整的执行了整个生命周期,而且第一个onPause首先执行,接着是finish
@Override protected void onCreate(Bundle savedInstanceState) { Log.e("xw", "111---onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); finish(); }
可以看到只执行了onCreate和与之对应的onDestroy,那么我们把finish放在onStart中,看看会发生什么
@Override protected void onStart() { Log.e("xw", "111---onStart"); finish(); super.onStart(); }
可以看到,同样如此,没有完整的执行整个生命周期
下面我们开始分析原因
首先我们要知道Activity的生命周期调用是由Framework中的AMS决定的,我们看看到底请求如何从应用传递到AMS
startActivity最终都会调用到startActivityForResult这个方法中,我们看看他做了什么
@Override public void startActivityForResult( String who, Intent intent, int requestCode, @Nullable Bundle options) { Uri referrer = onProvideReferrer(); if (referrer != null) { intent.putExtra(Intent.EXTRA_REFERRER, referrer); } Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, who, intent, requestCode, options); if (ar != null) { mMainThread.sendActivityResult( mToken, who, requestCode, ar.getResultCode(), ar.getResultData()); } cancelInputsAndStartExitTransition(options); }
关键在于mInstrumentation的execStartActivity方法
public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, String target, Intent intent, int requestCode, Bundle options) { ...... try { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(who); int result = ActivityManagerNative.getDefault() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target, requestCode, 0, null, options); checkStartActivityResult(result, intent); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } return null; }
其中ActivityManagerNative.getDefault()获取的就是AMS的代理类,我们可以利用它远程调用AMS的各种方法,在这里,我们将调用AMS的startActivity,这样请求就从应用传递给了AMS
接着看看finish方法
public void finish() { finish(DONT_FINISH_TASK_WITH_ACTIVITY); }private void finish(int finishTask) { if (mParent == null) { int resultCode; Intent resultData; synchronized (this) { resultCode = mResultCode; resultData = mResultData; } if (false) Log.v(TAG, "Finishing self: token=" + mToken); try { if (resultData != null) { resultData.prepareToLeaveProcess(this); } if (ActivityManagerNative.getDefault() .finishActivity(mToken, resultCode, resultData, finishTask)) { mFinished = true; } } catch (RemoteException e) { // Empty } } else { mParent.finishFromChild(this); } }
也是利用ActivityManagerNative.getDefault()将请求传递给了AMS
AMS收到消息后根据请求内部进行一系列操作,之后也是通过IPC调用,将需要的操作通知应用进程。
应用进程其实就是一个ActivityThread,而负责接收AMS消息的则是ActivityThread的一个内部类ApplicationThread,他也是一个binder,它里面的方法中很明显的有几个涉及基本的生命周期调用
scheduleLaunchActivity
scheduleResumeActivity
schedulePauseActivity
scheduleStopActivity
scheduleDestroyActivity
其中scheduleLaunchActivity适用于新建一个Activity,scheduleResumeActivity适用将已有的Activity重新展示,schedulePauseActivity由于之前所说的原因所以会单独调用,scheduleStopActivity适用于startActivity时旧的Activity,而scheduleDestroyActivity适用于finish是旧的Activity,可以看到也是除了schedulePauseActivity较为特殊,也是一一对应的关系。
下面我们看看scheduleLaunchActivity的具体实现
@Override public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { ...... sendMessage(H.LAUNCH_ACTIVITY, r); }
因为binder的代码会运行在他开启的线程中,所以要使用Handler将消息发送到主线程中,利用ActivityThread中H这个Handler来进行处理,看看H的处理方式
case LAUNCH_ACTIVITY: { ...... handleLaunchActivity(r, null, "LAUNCH_ACTIVITY"); } break;
调用到handleLaunchActivity方法中
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) { ...... Activity a = performLaunchActivity(r, customIntent); ...... handleResumeActivity(r.token, false, r.isForward,!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason); ...... }
关键的就是这两个,先看第一句performLaunchActivity
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ...... Activity activity = null; try { java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); ...... } ...... activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor, window); ...... if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } ...... r.activity = activity; r.stopped = true; if (!r.activity.mFinished) { activity.performStart(); r.stopped = false; } ...... return activity; }
重要的以下四点:
1:根据传递进的参数利用ClassLoader构建Activity类
2:调用Activity的attach的方法,里面将Activity的各种参数初始化,并且设置了Activity关联的PhoneWindow类,很重要,但是和现在讲的生命周期关系不大
3:mInstrumentation.callActivityOnCreate方法,在里面Activity调用了我们熟悉的onCreat方法
4:activity.performStart()里面调用了Activity的onStart方法,当然要调用的首先会判断mFinished的值,我们再看下前面的finish方法,里面在将消息发送给AMS后还将mFinished置为TRUE,这解释了为什么在onCreat调用finish后onStart方法不会被调用到。在调用完onStart之后还会将stopped置为false,这个将之后用于判断是否去执行onStop方法
看完performLaunchActivity,我们接着去看看handleResumeActivity方法,从名字就可以看出是用来调用onResume方法的
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) { ...... r = performResumeActivity(token, clearHide, reason); ...... ActivityManagerNative.getDefault().activityResumed(token); }public final ActivityClientRecord performResumeActivity(IBinder token, boolean clearHide, String reason) { ...... if (r != null && !r.activity.mFinished) { ...... r.activity.performResume(); r.paused = false; r.stopped = false; ...... } return r; }
也会判断mFinished的值,之后调用onResume。
如果正常情况下的话,scheduleLaunchActivity会使一个新的Activity对象被创建,并且成功调用onCreate,onStart,onResume方法,并将paused 和stopped 值置为false,最后将成功启动Activity的消息通知AMS
所以同理scheduleResumeActivity会去执行Activity的onStart和onResume方法,scheduleStopActivity和scheduleDestroyActivity也同样,拿schedulePauseActivity做个代表再说下,schedulePauseActivity发消息后会执行ActivityThread的handlePauseActivity方法
private void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport, int seq) { ActivityClientRecord r = mActivities.get(token); if (r != null) { ...... performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity"); ...... ActivityManagerNative.getDefault().activityPaused(token); } }
同样,调用performPauseActivity然后去通知AMS,看看performPauseActivity方法
final Bundle performPauseActivity(IBinder token, boolean finished, boolean saveState, String reason) { ActivityClientRecord r = mActivities.get(token); return r != null ? performPauseActivity(r, finished, saveState, reason) : null; }final Bundle performPauseActivity(ActivityClientRecord r, boolean finished, boolean saveState, String reason) { if (r.paused) { if (r.activity.mFinished) { // If we are finishing, we won't call onResume() in certain cases. // So here we likewise don't want to call onPause() if the activity // isn't resumed. return null; } ..... } ..... performPauseActivityIfNeeded(r, reason); ...... }
首先就告诉我们如果调用了finish但是没有调过onResume那么就什么都不做,直接返回,否则的话就会去调用performPauseActivityIfNeeded,里面会调用Activity的onPause方法。
- AMS与Activity的交互
- 跟着Innost理解下Activity 的启动以及与AMS的交互
- Activity启动时,与Ams,Wms如何交互
- Activity与AMS
- Android APP与AMS交互
- AMS对Activity的管理
- 源码阅读---AMS与Activity启动流程
- Fragment与Activity的交互
- Fragment与Activity的交互
- 跟着Innost理解下Service 的启动以及与AMS的交互
- Android ActivityManagerService(AMS)的Activity管理
- Android ActivityManagerService(AMS)的Activity管理
- Android 6.0 AMS分析的第二条线:以Launcher启动一个Activity为例,分析应用进程的创建、Activity的启动,以及他们和AMS之间的交互等知识;
- Android6.0 AMS启动Activity(六) AMS与PKMS关系(通过Intent获取ActivityInfo)
- Android6.0 AMS启动Activity(六) AMS与PKMS关系(通过Intent获取ActivityInfo)
- Android Activity与local service的交互
- Activity 应用与用户交互的工具
- android service与Activity的交互方式
- 离散化
- 机器学习相关算法的大总结(四)
- Spring AOP
- c编辑器之clion安装,编译,控制台乱码修复
- Spreading the Wealth,UVa 11300
- AMS与Activity的交互
- 【c++】菱形继承
- 我的conky安装与配置——基于ubuntu 16.04 LTS
- 数据库视图、变量、存储过程、变量及函数
- Unity3D之UI按键绑定事件(五)
- 浅谈项目系统架构分层
- 排列组合
- Spring boot war部署
- CAD 学习笔记 Mac