问题现象:
在刚安装完demo应用未登录任何帐号时,通过系统内的分享功能想将文件/图片等内容"发送给好友"或"发送到我的电脑",触发登录界面,但登录成功后,没有跳转到选择demo好友发送界面,无法继续发送。
代码分析:
demo中JumpActivity处理着各种外部应用分享入口,通过调试发现进行分享时会判断是否登录过,如果未登录则会跳转至LoginActivity进行登录。如下代码:
private void doShare(booleancheckLogin) { // 系统级分享 Intent intent = getIntent(); ... ... ... ... // 没登录 if (checkLogin &&!demo.isLogin()){ Intent i = newIntent(this, LoginActivity.class); i.putExtra("isActionSend",true); i.putExtras(extra); i.putExtras(i); startActivityForResult(i,SHARE_LOGIN_REQUEST); return; } ... ... }
查阅代码得知登录成功后,则JumpActivity.onActivityResult()将会得到requestCode值为SHARE_LOGIN_REQUEST的回调。为此,在onActivityResult()回调处设置断点,再次跟进。
设置断点,执行分享操作进行调试,发现每次执行完startActivityForResult(),则onActivityResult()便立刻被回调了,且resultCode值为RESULT_CANCEL。至些,问题开始有了头绪。
通过排查,发现LoginActivity在之前有被改动过,其launchMode赋值为singleTask。分享功能就是在这次改动之后失效了的。只要恢复launchMode为standard,即可让onActivityResult()在LoginActivity登录成功后正常回调回来,执行分享操作,恢复功能。
至此,问题得到解决,但问题原因仍是一头雾水:
为什么通过startActivityForResult()方式去启动launchMode=singleTask的Activity,onActivityResult()会被立即回调且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其launchMode为singleTask。
如果在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了),则LoginActivity的setResult()结果有可能不会传给JumpActivity。
继续按返回键,则才回到Activity 2。
问题结论:
由此,我们再回到先前的问题。在这种Tasks的入栈与出栈设计下,由于可能有Activity X的存在,所以在Activity 2启动Activity Y时,则直接回调了onActivityResult()并给出了RESULT_CANCEL也就可以理解了。
相关推荐
`startActivityForResult()`是Intent的一种特殊用法,它允许一个Activity启动另一个Activity,并期望在新Activity执行完特定操作后返回结果。下面将详细阐述`startActivityForResult()`的工作原理及其在实际开发中的...
在Android应用开发中,`startActivityForResult`是一个关键方法,用于在两个Activity之间进行交互,尤其是在需要从一个Activity启动另一个Activity并期待返回结果时。这个方法允许开发者在启动新的Activity时传递...
在启动Activity时,我们可以将数据放入Intent,然后在被启动的Activity中通过回调方法获取这些数据。 3. **启动另一个Activity并接收结果**:当Activity A启动Activity B时,可以使用`startActivityForResult()`...
在Android应用开发中,`startActivityForResult()`是一个关键方法,用于在不同的Activity之间进行通信,尤其是在需要从一个Activity返回结果到另一个Activity时。这个方法使得开发者可以启动一个新的Activity,并...
在Android应用开发中,`Activity`是用户界面的主要载体,而`startActivityForResult`方法则用于在一个`Activity`中启动另一个`Activity`并期待得到返回的结果。本文将深入探讨`Activity`的四种启动模式(Standard、...
除了`Activity`之间的交互,`Fragment`也可以通过`startActivityForResult()`启动`Activity`并接收结果,其回调方法同样在`Fragment`中实现,但需要重写`onActivityResult()`。 ### 结论 `startActivityForResult...
4. Activity之间的合作:Activity可以通过Intent传递数据,并使用startActivityForResult()进行回调,实现不同Activity间的交互。 六、Tasks and Back Stack: 1. 管理Task:Task是Android中的一系列Activity堆栈,...
在Android开发中,`startActivityForResult`方法是用于启动一个新的Activity并等待其返回结果的关键机制。通常情况下,当从子Activity返回时,我们需要重写`onActivityResult`回调来处理返回的数据。然而,随着...
同时,良好的编程实践是确保所有入口点都能够正确处理Activity的生命周期,比如在onCreate()、onStart()、onResume()等回调方法中进行必要的初始化和状态恢复。 总的来说,“042集-跨进程启动Activity和设置...
在页面传值中,回调可能涉及到启动Activity的结果处理,如使用startActivityForResult()启动Activity并重写onActivityResult()方法来接收返回的数据。 总结来说,Android页面间的传值方式多样,开发者可以根据具体...
例如,当我们从一个Activity启动另一个Activity并希望在后者返回结果时进行处理,可以使用`startActivityForResult()`方法,并在原始Activity中重写`onActivityResult()`方法,这就是一个简单的回调应用场景。...
然后,启动它的Activity会在`onActivityResult()`回调中接收到结果。 9. **权限管理**: 若启动的Activity需要特定权限,比如访问联系人或位置,那么在调用`startActivity()`之前,需要确保应用已经获得了相应的权限...
除了通过Intent传递参数外,Activity间还可以通过startActivityForResult()进行回调通信,或者使用BroadcastReceiver、EventBus、LiveData等组件进行更复杂的异步通信。 总结,Android的Activity是应用程序的核心...
5. 主Activity的`onActivityResult`回调方法被触发,根据请求码判断是哪个`StartActivityForResult`返回的结果,然后处理返回的数据。 ### 2. 使用步骤 #### 步骤1:创建Intent 在启动者Activity中,创建一个...
这里的`2`是一个任意选择的正整数,用于在`onActivityResult()`回调中识别此次启动Activity的请求。需要注意的是,启动Activity之后不要立即调用`finish()`方法,因为这会导致当前Activity被销毁,从而无法接收回传...
10. Activity有四种启动模式:标准模式(Standard)、单实例模式(SingleTop)、单任务模式(SingleTask)和单栈顶模式(SingleInstance),它们决定了Activity在Task中的行为。 九、权限管理 11. 如果Activity的...
比如,设置android:launchMode属性可以改变Activity的启动模式,如单实例(singleInstance)、单任务(singleTask)、单栈顶(singleTop)等,每种模式会影响Activity在栈中的位置和生命周期调用。 深入理解...
主要的生命周期回调方法包括: 1. `onCreate()`: 当Activity首次创建时调用,用于初始化界面和基本设置。 2. `onStart()`: 随后调用,表示Activity变得可见但可能不完全在前台。 3. `onResume()`: Activity进入前台...
在Android应用开发中,Activity是构成应用程序的基本组件,它代表用户界面的一个屏幕。有时,我们需要在子Activity...通过这种方式,不同Activity间的交互变得简单且灵活,极大地丰富了Android应用的功能和用户体验。