startActivityForResult无法调用singleTask的Activity

背景:

假设一个Activity A,需要用startActivityForResult方法开启Activity B。如果B的launch mode被设置为singleTask/singleTop,那么在B开启之后的瞬间(未等B返回任何result),A中的onActivityResult方法就会被调用,并且收到一个RESULT_CANCEL的request code。
 
原因:
如果被开启的B和开启B的A 这两个Activity不同时工作在一个task中,那么A的startActivityForResult就无法使用。
 
那么,在Android里,什么是task呢?
默认情况下,来自同一个应用的Activity存在于同一个task中。每个task里都维护着一个stack,这个stack里面记载着曾经开启并且没有被destroy的Activity。在stack的最顶部就是当前在foreground的Activity。当你在Home Screen中打开一个应用时,就相当于新开启了一个task。你每按一次back键,就相当于把这个task的stack的最顶部的Activity移除。但是同一个task的stack里,包含的也可以是来自不同应用程序的Activity(例如,你自己的应用可以start另一个浏览器的页面)。
当在AndroidManifest.xml中声明一个Activity的Launch Mode为singleTask时,在新建这个Activity时,会把它放在一个新的stack中并置于顶部(即放在新的task中)。如果这个Activity已经在某个task的stack中了,此时只会调用它的onNewIntent(),而不会调用onCreate()。
当在AndroidManifest.xml中声明一个Activity的Launch Mode为singleInstance时,与singleTask模式相同的是在新建这个Activity时,会把它放在一个新的stack中并置于顶部(即放在新的task中)。与singleTask模式不同的是,这个新建的task的stack永远只会有一个元素,就是这个Activity自己。如果这个Activity已经在某个Task的stack中了(这个stack必定只有一个元素,那就是这个Activity自己),此时只会调用它的onNewIntent(),而不会调用onCreate()。
 
解决办法:
如果你的B的确需要用到single task的Launch Mode,并且B确实需要返回给A一些数据,那么尝试在B中通过startActivity(Intent intent)重新开启A。只不过此时,你已经在intent里面添加了你想返回的数据了。

posted on 2014-12-17 15:53  sfce  阅读(1289)  评论(0编辑  收藏  举报

导航