簡體   English   中英

了解 Android 帶有啟動畫面的啟動模式

[英]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 。

我給你的建議如下:

  • 擺脫使用特殊啟動模式singleInstancesingleTask
  • 創建一個新的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM