Sobes.tech
Middle

Jak poradzić sobie z sytuacją, gdy aktywność otwiera się wielokrotnie z powodu deeplink?

sobes.tech AI

Odpowiedź od AI

Istnieje kilka podejść:

  1. Użycie flag w Intent:

    • FLAG_ACTIVITY_SINGLE_TOP: Jeśli aktywność jest już na szczycie stosu, zamiast tworzyć nową, wywoływana jest metoda onNewIntent().
    • FLAG_ACTIVITY_CLEAR_TOP: Jeśli aktywność już istnieje w stosie, wszystkie nad nią będą zakończone, a ona zostanie przeniesiona na szczyt.
    • W połączeniu z FLAG_ACTIVITY_NEW_TASK: Często używane z CLEAR_TOP do obsługi aktywności z innego zadania.
  2. Konfiguracja launchMode w AndroidManifest.xml:

    • singleTop: Podobnie jak FLAG_ACTIVITY_SINGLE_TOP przy uruchomieniu przez Intent.
    • singleTask: Aktywność jest korzeniem nowego zadania; jeśli już istnieje jej egzemplarz w jakimś zadaniu, zostanie przeniesiona na przód, a wszystkie nad nią aktywności zostaną zakończone.
    • singleInstance: Aktywność istnieje w własnym zadaniu i jest jedyną aktywnością w tym zadaniu.
  3. Sprawdzanie istnienia aktywności przed jej uruchomieniem:

    • Użyj ActivityManager do sprawdzenia aktualnego stosu aktywności. Podejście to jest mniej preferowane ze względu na złożoność i koszty.
  4. Reakcja na onNewIntent():

    • Przy użyciu singleTop lub FLAG_ACTIVITY_SINGLE_TOP cała logika obsługi deeplinka powinna być zaimplementowana w onNewIntent(), a nie w onCreate(). Nie zapomnij wywołać setIntent(intent) w onNewIntent(), aby zaktualizować dostępny Intent.

Przykład użycia launchMode="singleTop" i onNewIntent():

W 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>

W klasie aktywności YourDeeplinkActivity:

class YourDeeplinkActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_deeplink)
        // Wstępne przetwarzanie, gdy aktywność jest tworzona
        handleIntent(intent)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        // Ważne, aby zaktualizować Intent
        setIntent(intent)
        // Przetwarzanie nowego Intent (deeplink)
        handleIntent(intent)
    }

    private fun handleIntent(intent: Intent?) {
        intent?.data?.let { uri ->
            // Logika obsługi URI deeplink
            Log.d("DeeplinkActivity", "Odebrany deeplink: $uri")
            // Na przykład wyodrębnianie parametrów i nawigacja do odpowiedniego fragmentu
        }
    }
}

Wybór podejścia zależy od konkretnego scenariusza i pożądanego zachowania stosu aktywności. Najczęstszym rozwiązaniem dla deeplinków prowadzących do już istniejącej aktywności jest użycie launchMode="singleTop" i obsługa w onNewIntent().