分类

链接

2017 年 11 月
 12345
6789101112
13141516171819
20212223242526
27282930  

近期文章

热门标签

新人福利,免费薅羊毛

现在位置:    首页 > Android > 正文
共享办公室出租
关于Fragment 不响应onActivityResult的情况分析
Android 暂无评论 阅读(854)
  1. 大家都知道,可以通过使用 startActivityForResult()  onActivityResult() 方法来传递或接收参数。
  2.  
  3. 但你是否遭遇过onActivityResult()不执行或者未按预想的那样执行的情况呢?
  4.  
  5. 这里我总结了三种情况:
  6.  
  7. 1、执行startActivityForResult,没等到被调用的 Activity 返回,onActivityResult() 就被执行了。
  8. 找了很久,终于通过小道消息得知,这与 Activity 的加载模式(launchMode)有关,该属性可以在 AndroidManifest.xml 中设置。
  9. 原先将其设为 singleInstance,经测试,所有需要传递或接收的 Activity 不允许设置该属性,或只能设为标准模式,否则系统将在 startActivityForResult() 后直接调用 onActivityResult()。
  10.  
  11. Note that this method should only be used with Intent protocols
  12. * that are defined to return a result. In other protocols (such as
  13. * {@link Intent#ACTION_MAIN} or {@link Intent#ACTION_VIEW}), you may
  14. * not get the result when you expect. For example, if the activity you
  15. * are launching uses the singleTask launch mode, it will not run in your
  16. * task and thus you will immediately receive a cancel result.
  17.  
  18. 2、两个activity传递数据和返回数据时,请求方的onActivityResult始终无响应,通过debug调试模式也没见调用该方法。查看了 各种配置和程序代码,均未发现有错误之处。后来仔细阅读API说明,恍然大悟,原来是调用startActivityForResult的参数问题,即调 用时这样:
  19. startActivityForResult(intent, 0);是第二个参数的问题,该参数必须大于0才能在返回值,并激活onActivityResult方法。
  20. 我最开始是用的一个activity默认的常量:RESULT_OK,跟踪了代码后发现,该常量的值为-1,当然没法激活 onActivityResult方法了,随后随便修改为一个大于0的整数,程序即通跑成功。
  21. startActivityForResult(intent, 1); //这样就行了
  22.  
  23. API描述:
  24. @requestCode If >= 0, this code will be returned in onActivityResult() when the activity exits.
  25.  
  26.  3、在TabHost的子ActivitystartActivityForResult调用其他Activity时候遭遇到onActivityResult方法不响应的问题。可以通过调用ActivitygetCallingActivity()查看要接受数据的Activity
  27.  
  28. API这么解释的:
  29.  
  30. Return the name of the activity that invoked this activity. This is
  31. * who the data in {@link #setResult setResult()} will be sent to.
  32.  
  33. 举个列子,有两个ActivityABA中执行startActivityForResult1new IntentAB.class));
  34.  
  35. 即由A调到B,再B执行setResult后执行getCallingActivity(),显示A
  36.  
  37.  
  38. 解决办法如下:
  39.  
  40. 1.通过父Activity启动其他Activity;
  41.  
  42. 2.实现父ActivityonActivityResult方法,将该处接收到的请求转发给当前活动的子Activity;
  43.  
  44. 3.自定义一个转发接口用来实现第2步中的转发功能;
  45.  
  46. 4.Activity中实现第3步接口中的方法用来接收返回信息;
  47.  
  48.  
  49. 代码如下:
  50.  
  51. 1.通过父Activity启动其他Activity
  52. 1 getParent().startActivityForResult(new Intent(...), REQUEST_CODE); 
  53. 2.实现父ActivityonActivityResult方法
  54.  
  55. 3.自定义接口
  56. public interface OnTabActivityResultListener {
  57.  
  58. public void onTabActivityResult(int requestCode, int resultCode, Intent data);
  59.  
  60. }
  61.  
  62. 4.Activity需要实现onTabActivityResult方法
  63. @Override
  64.  
  65. public void onTabActivityResult(int requestCode, int resultCode, Intent data) {
  66.  
  67. if (requestCode == REQUEST_CODE >> resultCode == RESULT_OK) {
  68.  
  69. //实现该处逻辑
  70.         ...
  71.  
  72. }
  73.  
  74. }
  75. 总结:凡是Activity本身含有上次父类的情况都不能直接使用startActivityForResult,而要通过getParent(),通过父类调用此方法。
  76. 此种情况也适用于多重Fragment嵌套使用的情况。
  77. 理论上使用FragmentActivity  Fragment组合时,在Fragment中调用startActivityForResult方法,实际上是调用Fragment所依付的ActivitystartActivityForResult方法。然后Fragment
  78. Activity会先响应自身的onActivityResult方法,再传递到当前活动的Fragment中。此时,通过重载FragmentonActivityResult方法可以接受返回事件。
  79. 这里需要注意,如果重载了FragmentActivity onActivityResult方法,一定要调用super. onActivityResult(),否则Fragment中的 onActivityResult方法不会被调用。 
  80. 4FragmentActivityFragment组合使用,且使用多层Fragment组合(即Fragment内部有嵌套)。在底层Fragment中执行startActivityForResult方法后,FragmentonActivityResult方法没有被调用。
  81. 我重载了FragmentActivityonActivityResult方法,也增加了super.onActivityResult()。通过调试发现,FragmentActivityonActivityResult方法执行了,但是没有往下传递成功。后来翻看源码:
  82. FragmentActivity中的onActivityResult方法这样写的:
  83. @Override
  84. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  85. int index = requestCode>>16;
  86. if (index != 0) {
  87. index--;
  88. if (mFragments.mActive == null || index < 0 || index >= mFragments.mActive.size()) {
  89. Log.w(TAG, "Activity result fragment index out of range: 0x"
  90. + Integer.toHexString(requestCode));
  91. return;
  92. }
  93. Fragment frag = mFragments.mActive.get(index);
  94. if (frag == null) {
  95. Log.w(TAG, "Activity result no fragment exists for index: 0x"
  96. + Integer.toHexString(requestCode));
  97. }
  98. frag.onActivityResult(requestCode>0xffff, resultCode, data);
  99. return;
  100. }
  101.  
  102. super.onActivityResult(requestCode, resultCode, data);
  103. }

============ 欢迎各位老板打赏~ ===========

本文版权归Bruce's Blog所有,转载引用请完整注明以下信息:
本文作者:Bruce
本文地址:关于Fragment 不响应onActivityResult的情况分析 | Bruce's Blog

发表评论

留言无头像?