Activity-finish过程与result回调

### 使用方式

  通常我们使用Activity的finish方法和onBackPressed方法来结束当前Activity,其中手机按物理back键就是调用的onBackPressed,查看源码可以发现其实onBackPressed也是调用了finish。如果当前Activity是使用startActivityForResult(Intent, int)来打开的,就可以使用setResult(int, Intent)来返回一个结果。startActivityForResult的int参数叫requestCode,而setResult的int参数叫resultCode,前一个Activity被finish了之后,会把setResult的结果通过onActivityResult(int requestCode, int resultCode, Intent data)来回传给上一个Activity。

  在项目启动阶段使用onActivityResult来回传结果开发固然很爽,但当项目开发到一定的代码体量,或者说需要架构优化时,这个onActivityResult回调就会变得特别恶心。我们通过是在业务组件(非Activity)中能够拿到一个Activity对象,然后通过这个Activity来startActivityForResult,但这个时候我们却必须在Activity中重写onActivityResult来拿结果。其中有个解决思路是弄个空的Fragment来拿activityResult,但这需要取决于三点,第一是Activity得支持Fragment,第二是Activity的onActivityResult需要调用super的onActivityResult,第三是需要维护这个Fragment,因为fragment的状态有时候会报各种奇葩bug,各种no attach都会导致onActivityResult无法正常回调。当然,AndroidX已经解决了这个问题,具体可以参考[ActivityResultRegistryOwner回调](developer.android.com/r)。这个其实是使用了类似Lifecycle的思路。


### finish源码

  Activity中的finish方法实现上是调用了ActivityTaskManager.getService().finishActivity(mToken, resultCode, resultData, finishTask),这里的ActivityTaskManager.getService跟前面的startActivity过程一样,IActivityTaskManger的实现类都是ActivityManagerService(AMS)。AMS的finishActivity方法直接调用了ActivityTaskManager的finishActivity,这里看到最后try-catch中的一个if-selse,判断了finsiTask == Activity.FINISH_TASK_WITH_ACTIVITY。可以看到Activity的finsish方法是重载的,finish()调用了finish(int),其中传的参数是DONT_FINISH_TASK_WITH_ACTIVITY。也就是ActivityTaskManager的finsiActivity要走else。在else中调用了tr.getStack().requestFinishActivityLocked(token, resultCode, resultData, "app-request", true)。ActivityStack的requestFinishActivityLocked调用了其finishActivityLocked。在finishActivityResultsLocked方法中,将resultWho、requestCode、resultCode、resultData封装到ActivityResult对象中,并将ActivityResult对象添加到Activity的ActivityRecord的results列表中。在finishActivityResultsLocked之前还调用了adjustFocusedActivityStack,这是为了找到下一个能获取焦点的Activity。最后调用startPausingLocked方法来使当前被finish的Activity被pause。在ActivityStack的startPausingLocked方法中,跟Activity的启动过程一样,也是调用了mService.getLifecycleManager.scheduleTransaction来调用Client的pause,这次使用的是PauseActivityItem,会调用ActivityThread的handlePauseActivity。

  在下面调用的finishCurrentActivityLocked方法中将当前Activity设置为finishing状态,并调用destroyActivityLocked来调用其onDestory。这里还有一个addToStopping的操作,是将当前Activity添加到stop的列表中,使用ActivityStackSupervisor发送一个stop的消息将当前Activity stop掉。在destroyActivityLocked中主要有两个操作,一个是cleanUpActivityLocked,这是为了清除Activity的引用,并解除Activity绑定的服务。另一个是通知ActivityThread调用destroy,又是同样的操作,使用mService.getLifecycleManager().scheduleTransaction,使用的是DestroyActivityItem,可以看到其execute方法中调用了client.handleDestroyActivity方法,也就是ActivityThread的handleDestroyActivity方法。代码中没有直接调用StopActivityItem的地方,但刚才addToStopping的操作,会给ActivityStackSupervisor的ActivityStackSupervisorHandler发一个消息,调用其ActivityIdleInternal方法,最终会调stack.stopActivityLocked,在其中一样使用mService.getLifecycleManager().scheduleTransaction,使用StopActivityItem来调用ActivityThread的handleStopActivity方法。

  可以发现Activity的所有生命周期都是通过ActivityThread来调的,ActivityThread作为XXXActivityItem的client,AMS通过ActivityStack使用getLifecycleManager触发transaction来调用ActivityItem。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值