本文转自:http://blog.csdn.net/sodino/article/details/22101881
问题现象:
在刚安装完demo应用未登录任何帐号时,通过系统内的分享功能想将文件/图片等内容"发送给好友"或"发送到我的电脑",触发登录界面,但登录成功后,没有跳转到选择demo好友发送界面,无法继续发送。
本文为Sodino所有,转载请注明出处:http://blog.csdn.net/sodino/article/details/22101881
代码分析:
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也就可以理解了。
相关推荐
Android之Intent通过startActivityForResult方法启动新Activity
singleTask和startActivityForResult的纠葛(activity的重建/onActivityResult回调为0) 问题验证: 1.startActivityForResult打开singleTask模式的活动,singTask失效。(见Action2) 2.singleTask模式的活动...
android startActivityForResult实现Acitvity的回调 最常见的登录运用.
基于RxPermissions框架思想,在使用startActivityForResult可以不重写onActivityResult回调
在Activity的四种不同的启动模式下,对于startActivityForResult方法的影响。什么时候可以收到回传数据。
2、启动activity-显示启动和隐式启动: 3、隐式启动自己的activity 4、获取隐启动传递过来的data数据 5、显示启动传递数据 6、禁用掉横竖屏切换 7、开启activity获取返回值-startActivityForResult:
startActivityForResult过时.md
使用startActivityForResult回传数据
简单的去理解 启动activity的方式 主要是介绍了 startActivityForResult 这个API
Activity跳转之startActivityForResult
定义了4个Activity,主activity跳转到其他2个时附带String good,第二个在接收到数据后将String +"boy"后返回给主Activity并Toast;第三个在接收到数据后将String +"boy&girl"后返回给主Activity并Toast。第4个采用...
介绍了StartActivityForResult的运用,并总结了一些问题及答案,可供初学者参考,代码无误,放心运行!
Activity启动,catogory action的使用,以及使用startActivityForResult启动的一些问题。
使用StartActivityForResult进行Activity跳转传值的小例子
React 与安卓交互 通过startActivityForResult启动Activity,获取Activity Result值回调信息。需要自己添加node_modules,node_modules文件太大上传不了。忘记写注释了,在java里通过Promise.resolve(result)异步回调...
3个方法的介绍和使用 startActivityForResult(Intent intent, int requestCode ) onActivityResult(int requestCode ,int resultCode, Intent data) setResult(int resultCode,intent intent)
Android 页面回调跳转(startActivityForResult)
这里实现的效果是,点击a Activity后,屏幕会跳转到手机的通讯录,任意选择点击一个通讯录中的联系人,则从通讯录Activity跳回到a Activity并在a Activity上显示你刚才选择通讯录联系人的名字。
而且要从Activity中返回数据,虽然返回数据和传递数据类似,也可以采用前面4种方法,但是一般建议采用Intent对象的方式来返回数据,使用这种方式返回数据,需要使用startActivityForResult方法来显示Activity ...