### 使用方式

  通常我们使用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回调](https://developer.android.com/reference/androidx/activity/result/ActivityResultRegistryOwner?hl=en)。这个其实是使用了类似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。

android finish 判断当前_Activity-finish过程与result回调相关推荐

  1. Android世界第一个activity启动过程

    Android世界第一个activity启动过程 第一次使用Markdown,感觉不错. Android系统从按下开机键一直到launcher的出现,是一个如何的过程,中间都做出了什么操作呢.带着这些 ...

  2. Android 7.0 Audio的Resample过程详解

    Android 7.0 Audio的Resample过程详解 Qidi 2017.02.23 (Markdown & Haroopad) [前言] 处理过音频文件的工程师都知道音频数据存在采样 ...

  3. [ Android实战 ] 判断文件是否为软链接或硬链接

    [ Android实战 ] 判断文件是否为软链接或硬链接 背景 硬链接和软链接的区别 file.getCanonicalPath Files.isSymbolicLink path.toRealPat ...

  4. android中怎么网络判断,Android中判断网络是否连接实例详解

    Android中判断网络是否连接实例详解 在android中,如何监测网络的状态呢,这个有的时候也是十分重要的,方法如下: public class ConnectionDetector { priv ...

  5. android列表滑到底部,Android中判断listview是否滑动到顶部和底部的实现方法

    今天实现listview的下拉刷新和上拉加载的时候,遇到了一个问题,*就是说需要根据listview中滑动的位置来进行下拉刷新和上拉加载.* 具体点,只有当我的listview滑动到最顶部的时候,这时 ...

  6. android 如何判断有没有网络

    //从项目取出来的代码,android  如何判断有没有网络,分享一下 protected static int getAPNType(Context context) { //给网络设置值 int ...

  7. Android之判断是否有网封装类

    Android之判断是否有网封装类                  我们做项目的时候,一般都不能离开网络,下面是对判断是否有网类的封装 import android.content.Context; ...

  8. Android检测是否有悬浮窗,Android 获取判断是否有悬浮窗权限的方法

    现在很多应用都会用到悬浮窗,很多国产rom把悬浮窗权限加入控制了,你就需要判断是否有悬浮窗权限,然后做对应操作. Android 原生有自带权限管理的,只是被隐藏了.看android源码在androi ...

  9. android 判断对象,Android网络判断知识小结

    Android中判断当前网络是否可用 应用场景:实现判断当前网络是否可用 当前有可用网络,如下图: 当前没有可用网络,如下图: 实现步骤: 1.获取ConnectivityManager对象 Cont ...

最新文章

  1. [Spring 深度解析]第5章 Spring之DAO
  2. 解决IDM“警告:您在以管理员身份运行IDM,在该模式下,IDM无法接管浏览器的下载事件”的问题。
  3. Vue之旅-Vue环境搭建
  4. Servlet获取URL地址
  5. 《西游记》原著的一点读后感
  6. mysql mode_MYSQL中的sql_mode模式
  7. python链表结构_CodeSalt | Python数据结构的实现 — 链表
  8. C++资源之不完全导引(下)
  9. springmvc json串的null值替换为空值
  10. 计算机普通话培训开班简报,普通话培训第四期简报.doc
  11. dell台式计算机主板电池,怎么更换主板电池 主板电池更换方法【步骤详解】
  12. 从视频中提取为ppt或图片
  13. 3.1.4_cardView原理解析
  14. 十大模拟炒黄金白银的软件
  15. 序号47指标横向展示.xlsx_杭州增加2万个小客车指标!想拥有“浙A”车牌,这个APP一定要收好~...
  16. 高通ISP流程中,ADRC Gain与GTMLTM的对应关系
  17. VScode comment translate 无法使用问题
  18. 群晖docker给showdoc添加ssl证书
  19. COMSOL如何绘制紧贴圆柱面的圆面
  20. 3Dmap generator绘制三维地形

热门文章

  1. 双交线/光纤/光缆/芯数
  2. ESP8266 WiFi 模块连接乐为物联云实现PM2.5测试系统
  3. 及早应对欧美新标准UL/IEC/EN 62368-1:2014,TUV莱茵专家有妙招
  4. 【EasyExcel】在SpringBoot+VUE项目中引入EasyExcel实现对数据的导出(封装工具类)
  5. WINDOWS系统电脑禁用服务端口
  6. LLVM IR学习记录(1) GetElementPtr指令
  7. 日记-2020-11-10
  8. lombok 的var 使用时报错
  9. web 端渲染优化指北
  10. mvel 调用java_Mvel使用指南