`

startActivityForResult启动singleTask的Activity,则onActivitResult()立即回调且resultCode为RE

阅读更多

本文转自:http://blog.csdn.net/sodino/article/details/22101881

 

问题现象:

          在刚安装完demo应用未登录任何帐号时,通过系统内的分享功能想将文件/图片等内容"发送给好友"或"发送到我的电脑",触发登录界面,但登录成功后,没有跳转到选择demo好友发送界面,无法继续发送。

 

        本文为Sodino所有,转载请注明出处:http://blog.csdn.net/sodino/article/details/22101881

代码分析:

         demo中JumpActivity处理着各种外部应用分享入口,通过调试发现进行分享时会判断是否登录过,如果未登录则会跳转至LoginActivity进行登录。如下代码:

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. private void doShare(booleancheckLogin) {  
  2.           // 系统级分享  
  3.           Intent intent = getIntent();  
  4.           ... ...  
  5.           ... ...  
  6.            
  7.           // 没登录  
  8.           if (checkLogin &&!demo.isLogin()){  
  9.                    Intent i = newIntent(this, LoginActivity.class);  
  10.                    i.putExtra("isActionSend",true);  
  11.                    i.putExtras(extra);  
  12.                    i.putExtras(i);  
  13.                    startActivityForResult(i,SHARE_LOGIN_REQUEST);  
  14.                    return;  
  15.           }  
  16.           ... ...  
  17. }  

         查阅代码得知登录成功后,则JumpActivity.onActivityResult()将会得到requestCode值为SHARE_LOGIN_REQUEST的回调。为此,在onActivityResult()回调处设置断点,再次跟进。

        

         设置断点,执行分享操作进行调试,发现每次执行完startActivityForResult(),则onActivityResult()便立刻被回调了,且resultCode值为RESULT_CANCEL。至些,问题开始有了头绪。

         通过排查,发现LoginActivity在之前有被改动过,其launchMode赋值为singleTask。分享功能就是在这次改动之后失效了的。只要恢复launchMode为standard,即可让onActivityResult()在LoginActivity登录成功后正常回调回来,执行分享操作,恢复功能。

        

         至此,问题得到解决,但问题原因仍是一头雾水:

为什么通过startActivityForResult()方式去启动launchMode=singleTaskActivityonActivityResult()会被立即回调且resultCode值为RESULT_CANCEL??   

     

原因解析:

经查文档,发现文档中另一相似的方法startActivityForResult(Intent,int,Bundle)有说明如下:

Note that this method should only be used with Intent protocols thatare defined to return a result. In other protocols (such as ACTION_MAIN orACTION_VIEW), you may not get the result when you expect. For example,if the activity you are launching uses thesingleTask launch mode, it will not run in your task and thus you willimmediately receive a cancel result.

 

但这点注释让人理解得仍不是很透彻。继续搜索,发现文档(点击这里)里说了下面的这一种现象。

在下图中,存在着前两个栈,其中直接显示在屏幕上与用户交互的Back Stack,及另一个隐藏在后台的Background Task,该栈栈顶的Activity Y其launchModesingleTask

如果在Activity 2中调用BackgroundTask中已经启动过的Activity Y,则Background Task内占据屏幕并且该Task下所有的栈都会保留当前的栈位置及顺序push进Back Task形成新的结构,顺序由上至下为Activity Y→Activity X→Activity 2→Activity 1。

在Activity Y界面按返回键,则ActivityY出栈,Activity X占据屏幕!注意,由Activity2调用的Activity Y,但返回键后,回退显示的是Activity X所以即使在Activity Y执行setResult(),Activity 2也是无法接收到的。换回文章开头的问题,即在JumpActivity处启动LoginActivity(已经被设置singleTask),则LoginActivitysetResult()结果有可能不会传给JumpActivity

继续按返回键,则才回到Activity 2。

 

 

 

问题结论:

由此,我们再回到先前的问题。在这种Tasks的入栈与出栈设计下,由于可能有Activity X的存在,所以在Activity 2启动Activity Y时,则直接回调了onActivityResult()并给出了RESULT_CANCEL也就可以理解了。

分享到:
评论

相关推荐

    Android之Intent通过startActivityForResult方法启动新Activity

    `startActivityForResult()`是Intent的一种特殊用法,它允许一个Activity启动另一个Activity,并期望在新Activity执行完特定操作后返回结果。下面将详细阐述`startActivityForResult()`的工作原理及其在实际开发中的...

    activity的回调

    在启动Activity时,我们可以将数据放入Intent,然后在被启动的Activity中通过回调方法获取这些数据。 3. **启动另一个Activity并接收结果**:当Activity A启动Activity B时,可以使用`startActivityForResult()`...

    ActivityForResult实现Activity回调

    除了`Activity`之间的交互,`Fragment`也可以通过`startActivityForResult()`启动`Activity`并接收结果,其回调方法同样在`Fragment`中实现,但需要重写`onActivityResult()`。 ### 结论 `startActivityForResult...

    测试Activity的四种启动模式对startActivityForResult的影响

    当启动一个SingleTask`Activity`时,系统会检查栈中是否存在该`Activity`,如果存在,就会清除它上面的所有`Activity`,然后将请求的结果通过`onActivityResult`回调。如果不存在,系统会创建新的`Activity`实例并放...

    StartActivityForResult小例子

    5. 主Activity的`onActivityResult`回调方法被触发,根据请求码判断是哪个`StartActivityForResult`返回的结果,然后处理返回的数据。 ### 2. 使用步骤 #### 步骤1:创建Intent 在启动者Activity中,创建一个...

    带返回值的Activity启动

    `startActivityForResult`方法是Android SDK提供的一种特殊启动Activity的方式,主要用于实现从一个Activity(我们称之为"启动者"或"父Activity")启动另一个Activity("被启动者"或"子Activity"),并在子Activity...

    Android-基于RxPermissions框架思想在使用startActivityForResult可以不重写onActivityResult回调

    在Android开发中,`startActivityForResult`方法是用于启动一个新的Activity并等待其返回结果的关键机制。通常情况下,当从子Activity返回时,我们需要重写`onActivityResult`回调来处理返回的数据。然而,随着...

    关于Activity与Fragment混用中对于startActivityForResult方法的解析示例

    当目标Activity执行完并调用`finish()`方法时,系统会回调当前Activity的`onActivityResult()`方法,传入`requestCode`和`resultCode`以及可能的数据。 在Fragment中,由于直接调用`startActivityForResult()`会...

    StartActivityForResult

    在Android应用开发中,`StartActivityForResult`是一个关键的组件交互方法,用于在一个Activity(活动)启动另一个Activity并期望得到返回结果。这个方法允许开发者在应用程序的不同组件之间传递数据,通常用于实现...

    startActivityForResult的详细用法

    在Android应用开发中,`startActivityForResult`是一个非常重要的方法,它允许我们在启动一个Activity时传递数据,并在那个Activity执行完后返回结果到调用它的Activity。这个过程涉及到Intent、生命周期管理和数据...

    【android】的startActivityForResult

    在目标Activity结束时,系统会回调`Activity.onSaveInstanceState`保存状态,然后调用`onStop`和`onDestroy`。当结果返回时,会调用`onActivityResult`。 **五、应用场景** 1. **选择图片或文件**:从图库或文件...

    startActivityForResult Demo

    启动Activity会在它的`onActivityResult`回调方法中接收到返回的结果。 以下是使用`startActivityForResult`的基本步骤: 1. **创建Intent**:首先,你需要创建一个Intent对象,指定要启动的Activity。 ```java ...

    Activity启动

    启动Activity的原Activity会在其`onActivityResult()`回调中接收到这些结果,从而可以根据返回数据做出相应的处理。 以下是一个简单的`startActivityForResult()`示例: ```java Intent intent = new Intent(this,...

    案例八(启动带有返回值的activity

    这个过程通常通过Intent、startActivityForResult()方法和onActivityResult()回调来实现。 首先,我们需要创建一个Intent对象,它是一个用来在组件之间传递数据的类。在启动带有返回值的Activity时,我们会在Intent...

    inline-activity-result,在回调中内联接收活动结果,不带任何样板文件。.zip

    "inline-activity-result"的核心思想是简化Activity间通信的过程,它将`onActivityResult()`回调与`startActivityForResult()`紧密集成,减少了代码冗余。通过使用Lambda表达式或者Kotlin的扩展函数,开发者可以直接...

    启动Activity

    本文将深入探讨如何使用`startActivityForResult` API来启动一个Activity,并理解其背后的机制。 首先,让我们了解Activity的基本概念。Activity是一个可以与用户进行交互的可视组件,它承载了用户界面的所有元素,...

    042集-跨进程启动Activity和设置Activity多个入口

    同时,良好的编程实践是确保所有入口点都能够正确处理Activity的生命周期,比如在onCreate()、onStart()、onResume()等回调方法中进行必要的初始化和状态恢复。 总的来说,“042集-跨进程启动Activity和设置...

    startActivityForResult使用方式

    Intent用于描述要启动的目标Activity,请求码则用于在结果回调时区分不同的启动操作。 ```java Intent intent = new Intent(this, SecondActivity.class); startActivityForResult(intent, REQUEST_CODE); ``` ...

Global site tag (gtag.js) - Google Analytics