Andorid Activity提供了startActivityForResult方法來(lái)實(shí)現(xiàn)打開(kāi)另一個(gè)頁(yè)面獲取并回調(diào)結(jié)果的操作。但在某些情況下,startActivityForResult會(huì)出現(xiàn)無(wú)效的情況。
相關(guān)書(shū)籍中的解釋
在《Android群英傳》書(shū)中有這么一段話
"如果在一個(gè) singleTop 或者 singleInstance 的 ActivityA 中通過(guò) startActivityForResult()方法來(lái)啟動(dòng)另一個(gè) ActivityB,那么系統(tǒng)將直接返回 Activity.RESULT_CANCELED 而不會(huì)再去等待返回,這是由于系統(tǒng)在 Framework 層做了對(duì)這兩種啟動(dòng)模式的限制,因?yàn)?Android 開(kāi)發(fā)者認(rèn)為,不同 Task 之間默認(rèn)是不能傳遞數(shù)據(jù)的,如果一定要傳遞,那則只能通過(guò) Intent 來(lái)綁定數(shù)據(jù)。 "
首先,說(shuō)明下這句話適用于Android 5.0(api 21)以下的系統(tǒng),在5.0及以上的系統(tǒng)中不存在該問(wèn)題。也就是startActivityForResult()正常工作。
其次結(jié)合自己開(kāi)發(fā)測(cè)試的實(shí)例,發(fā)現(xiàn)上面singleTop應(yīng)該換成singleTask,因?yàn)閟ingleTop無(wú)關(guān)不同的Task,而singleInstance和singleTask都是有關(guān)不同task操作的,singleTop模式下并沒(méi)有出現(xiàn)Activity.RESULT_CANCELED的情況。
Android Api關(guān)于startActivityForResult的解釋
Launch an activity for which you would like a result when it finished. When this activity exits, your onActivityResult() method will be called with the given requestCode. Using a negative requestCode is the same as calling startActivity(Intent)
(the activity is not launched as a sub-activity).
Note that this method should only be used with Intent protocols that are defined to return a result. In other protocols (such as ACTION_MAIN
or ACTION_VIEW
), you may not get the result when you expect. For example, if the activity you are launching uses FLAG_ACTIVITY_NEW_TASK
, it will not run in your task and thus you will immediately receive a cancel result.
這里說(shuō)明了startActivityForResult()只適用于Intent顯式啟動(dòng)Activity。而且在FLAG_ACTIVITY_NEW_TASK情況下,也就是新建任務(wù)棧時(shí)來(lái)存放待啟動(dòng)Activity時(shí),startActivityForResult()是無(wú)效的,這里也說(shuō)明了不同task之間沒(méi)有效果,經(jīng)過(guò)測(cè)試,同樣在api 21以下是這樣,以上不是這樣了,但文檔上沒(méi)有標(biāo)注。
測(cè)試驗(yàn)證
測(cè)試的例子很簡(jiǎn)單,新建一個(gè)android項(xiàng)目,里面三個(gè)Activity,分別進(jìn)行設(shè)置不同launchMode進(jìn)行startActivityForResult()跳轉(zhuǎn),并且在不同版本機(jī)型下測(cè)試。以下記錄下測(cè)試結(jié)果
(?表明在onActivityResult()中正常獲取結(jié)果;?表示在onActivityResult()中立即獲取了Activity.RESULT_CANCELED的結(jié)果):
| startActivityForResult | api>=21 | api<=19 |
|---|---|---|
| A(standard)---->B(singleTop) | ? | ? |
| A(standard)---->B(singleTask) | ? | ? |
| A(standard)---->B(singleInstance) | ? | ? |
| A(singleTop)---->B(standard) | ? | ? |
| A(singleTask)---->B(standard) | ? | ? |
| A(singleInstance)---->B(standard) | ? | ? |
結(jié)果表明在21之后,startActivityForResult()做了處理,適用于所有的啟動(dòng)模式了。
在實(shí)際開(kāi)發(fā)中需要注意到這里的適配,容錯(cuò)。
其他
《Android群英傳》p202