Sobes.tech
Middle

Jak zvládnout situaci, kdy se aktivita otevírá několikrát kvůli deeplink?

sobes.tech AI

Odpověď od AI

Existuje několik přístupů:

  1. Použití flagů v Intentu:

    • FLAG_ACTIVITY_SINGLE_TOP: Pokud je aktivita již na vrcholu zásobníku, volá se metoda onNewIntent() místo vytvoření nového instance.
    • FLAG_ACTIVITY_CLEAR_TOP: Pokud aktivita již existuje v zásobníku, všechny nad ní jsou ukončeny a aktivita je přesunuta na vrchol.
    • Ve spojení s FLAG_ACTIVITY_NEW_TASK: Často se používá s CLEAR_TOP pro práci s aktivitami z jiného úkolu.
  2. Nastavení launchMode v AndroidManifest.xml:

    • singleTop: Podobně jako FLAG_ACTIVITY_SINGLE_TOP při spuštění přes Intent.
    • singleTask: Aktivita je kořenem nového úkolu; pokud již existuje její instance v nějakém úkolu, je přesunuta dopředu a všechny nad ní jsou ukončeny.
    • singleInstance: Aktivita existuje ve vlastním úkolu a je jedinou aktivitou v tomto úkolu.
  3. Kontrola existence aktivity před spuštěním:

    • Použijte ActivityManager k ověření aktuálního zásobníku aktivit. Tento přístup je méně preferovaný kvůli složitosti a režii.
  4. Reakce na onNewIntent():

    • Při použití singleTop nebo FLAG_ACTIVITY_SINGLE_TOP by veškerá logika zpracování deeplink měla být implementována v metodě onNewIntent(), nikoliv v onCreate(). Nezapomeňte volat setIntent(intent) uvnitř onNewIntent() pro aktualizaci Intentu.

Příklad použití launchMode="singleTop" a onNewIntent():

V AndroidManifest.xml:

<activity
    android:name=".YourDeeplinkActivity"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="your_scheme"
              android:host="your_host"
              android:pathPrefix="/your_path" />
    </intent-filter>
</activity>

V třídě aktivity YourDeeplinkActivity:

class YourDeeplinkActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_deeplink)
        // Počáteční zpracování, pokud je aktivita vytvářena
        handleIntent(intent)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        // Je důležité aktualizovat Intent pro getIntent()
        setIntent(intent)
        // Zpracování nového Intentu (deeplink)
        handleIntent(intent)
    }

    private fun handleIntent(intent: Intent?) {
        intent?.data?.let { uri ->
            // Logika zpracování URI deeplink
            Log.d("DeeplinkActivity", "Received deeplink: $uri")
            // Například extrakce parametrů a navigace na požadovaný fragment
        }
    }
}

Volba přístupu závisí na konkrétním scénáři použití a požadovaném chování zásobníku aktivit. Nejčastějším řešením pro deeplink, které odkazují na již existující aktivitu, je použití launchMode="singleTop" a zpracování v onNewIntent().