[英]Understanding Android Launch modes with splash screens
我有 3 個活動: Splash (啟動器)、登錄、儀表板。 當應用程序打開時,Splash 會等待一段時間,然后開始登錄,自行finish
。 然后用戶可以從登錄導航到儀表板。
每當用戶點擊主頁按鈕或通過可瀏覽的 Intent 指向應用程序時,我想維護應用程序的單個實例。 以便用戶返回到切換應用程序之前他或她所在的位置。
以下是android:launchMode="standard"
和singleInstancePerTask
的行為(紅色方塊是已完成的活動)
singleTask
的行為類似於標准模式的附加 web 意圖,我可以向 Splash 添加邏輯,以便它中斷處理並在它不是 root 時完成:
最后,如果我選擇singleInstance
,會發生以下情況:
這似乎可行,但有些事情我不明白。 為什么第二個 Splash 忽略啟動登錄活動的 Intent? . 邏輯告訴我應該啟動登錄#2。
體現在物質上:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.testintentflags">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.TestIntentFLags">
<activity
android:name=".SplashActivity"
android:exported="true" android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="demo.intents.com"
android:scheme="https" />
</intent-filter>
</activity>
<activity
android:name=".DashboardActivity"
android:exported="false" />
<activity
android:name=".LoginActivity"
android:exported="false" />
</application>
</manifest>
這里發生了很多事情,我將嘗試解決這些問題:
首先,在這里使用launchMode="singleInstance"
是有問題的,因為您還沒有為您的任何活動聲明任何taskAffinity
。 因此,您的SplashActivity
和其他活動具有相同的(默認) taskAffinity
,它告訴 Android 所有這些活動都希望在同一任務中運行,這與您的SplashActivity
啟動模式聲明沖突。 這很糟糕,你不應該這樣做。 如果你真的想讓活動在單獨的任務中運行,你應該確保它們有不同taskAffinity
以免造成混淆。
其次,你寫道:
這似乎可行,但有些事情我不明白。 為什么第二個 Splash 忽略 Intent to launch Login 活動?。 邏輯告訴我應該啟動登錄#2。
這里發生的事情是這樣的:當SplashActivity
調用startActivity()
來啟動LoginActivity
時,使用的Intent
包含FLAG_ACTIVITY_NEW_TASK
集(因為SplashActivity
是用launchMode="singleInstance"
聲明的,所以它必須將其他活動啟動到新任務中),所以 Android 看起來對於將LoginActivity
作為其根Activity
的現有任務。 如果找不到,它會簡單地啟動一個新的LoginActivity
實例到一個新任務中。 但是,在這種情況下,它會找到一個(這是圖中的任務 #2),因此它只是將該任務帶到前台,而不啟動LoginActivity
的新實例。
這與運行應用程序時發生的行為相同,然后按下主頁按鈕,然后再次單擊該應用程序的應用程序圖標。 在這種情況下,Android 不會啟動應用程序的根Activity
的新實例,它只是查找將應用程序的啟動Activity
作為其根Activity
的現有任務,並將該任務帶到前台,無論它所在的是 state 。
我給你的建議如下:
singleInstance
和singleTask
BridgeActivity
,用作 web 瀏覽器和您的應用程序之間的橋梁。 此Activity
應該具有瀏覽器Intent
的<intent-filter>
。BridgeActivity
應該檢查它是否是其任務中的根Activity
。 如果不是,則意味着它已經啟動到一個已被帶到前台的現有任務中,它可以在onCreate()
中悄悄地finish()
)。BridgeActivity
檢測到它是其任務的根,它可以啟動SplashActivity
(確保設置FLAG_ACTIVITY_NEW_TASK
)以開始一個新任務(因為您的應用顯然還沒有現有任務)BridgeActivity
,這樣它就不會出現在任務堆棧歷史記錄或最近任務列表中( noHistory="true"
和excludeFromRecents="true"
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.