2013-08-19 121 views
0

我有一系列活動的Android應用程序。其中一項活動(我們稱之爲LoginSettings)需要登錄OAuth服務。我給了它一個按鈕,通過Intent啓動網絡瀏覽器。 LoginSettings不能使用singleTasksingleInstance啓動模式,因爲它需要保持在其前任活動的堆棧之上。也就是說,如果用戶從LoginSettings按下返回,則需要顯示堆棧中的先前活動,並且如果用戶稍後重新啓動我的應用程序,則無法重新啓動以顯示堆棧中的先前活動。打破像singleTask中間的堆棧沒有用處。如何在用戶在瀏覽器中登錄後顯示相同的Activity實例,而不啓動launchMode =「singleTask」?

我已經使用網絡瀏覽器和自定義回調URL和意圖過濾器的技巧,但因爲我不能使用singleTask,我不能得到結果到LoginSettings的同一個實例:它總是創建一個新活動,即使launchModesingleTop。期望的行爲是,在用戶登錄後,瀏覽器窗口消失,用戶看到LoginSettings,仍然在其後面的堆棧中。

我想使用瀏覽器而不是WebView進行身份驗證:首先,因爲它顯示用戶他們真正訪問目標網站,而不是給我的應用程序提供他們的密碼;其次,因爲用戶可能已經在瀏覽器中保存了密碼(或者可能已經登錄)。

回答

0

我終於找到了一個有用的把戲。當LoginSettings啓動瀏覽器時,它確保將FLAG_ACTIVITY_NEW_TASK標誌添加到啓動瀏覽器的Intent。 (這可能不會有什麼區別,因爲無論如何瀏覽器都是singleTask,但最好是確定的。)我創建了一個新的活動,而不是爲我的自定義URL提供LoginSettings意圖過濾器。此新活動顯示爲對話框,並且清單中沒有allowTaskReparenting。它顯示進度條和消息,而AsyncTask在驗證器中進行並交易驗證令牌。當AsyncTask完成時,它調用moveTaskToBack(true)然後結束。這將包含(僅)瀏覽器和對話框的任務移動到後面,顯示前一個任務,其中包含導致LoginSettings的活動堆棧。

在我的應用程序,無論是LoginSettings這個新的對話框使用OOB機制來談談實際管理和存儲AUTH憑證,以便LoginSettings.onResume檢查與後端用戶是否現在登錄,並替換登錄類如果是的話。作爲替代方案,您可以使用廣播來傳達登錄事件,但不要忘記當廣播發生時LoginSettings將處於停止狀態。

從理論上講,如果瀏覽器將FLAG_ACTIVITY_NEW_TASK標誌添加到Intent它會啓動自定義回調URL,但我已經使用Firefox和Chrome進行了測試,並且它可以與它們完美協作,這可能會出錯。另外,從理論上講,包含LoginSettings的任務可能會在後臺被銷燬。這也是基於singleTask的解決方案的一個問題:如果發生這種情況,您需要準備通過onCreate而不是onNewIntent來回撥URL。但通過我的解決方案,由於對話框完成登錄並保存憑證,當用戶回到LoginSettings時,即使從頭開始重新創建活動,它們也會登錄。

相關問題