Sobes.tech
Middle

Как да се справим със ситуацията, когато активността се отваря няколко пъти заради deeplink?

sobes.tech AI

Отговор от AI

Има няколко подхода:

  1. Използване на флагове в Intent:

    • FLAG_ACTIVITY_SINGLE_TOP: Ако активността вече е в върха на стека, се извиква методът onNewIntent() вместо създаване на нов екземпляр.
    • FLAG_ACTIVITY_CLEAR_TOP: Ако активността вече съществува в стека, всички активности над нея се затварят и тя се премества на върха.
    • В комбинация с FLAG_ACTIVITY_NEW_TASK: Често се използва с CLEAR_TOP за работа с активности от друга задача.
  2. Настройка launchMode в AndroidManifest.xml:

    • singleTop: Аналогично на FLAG_ACTIVITY_SINGLE_TOP при стартиране чрез Intent.
    • singleTask: Активността е корен на нова задача; ако вече съществува екземпляр в някоя задача, тя се прехвърля напред, а всички активности над нея се затварят.
    • singleInstance: Активността съществува в собствена задача и е единствената активност в тази задача.
  3. Проверка за съществуване на активност преди стартиране:

    • Използвайте ActivityManager за проверка на текущия стек от активности. Този подход е по-малко предпочитан поради сложността и разходите.
  4. Реакция на onNewIntent():

    • При използване на singleTop или FLAG_ACTIVITY_SINGLE_TOP, цялата логика за обработка на deeplink трябва да бъде реализирана в метода onNewIntent(), а не в onCreate(). Не забравяйте да извикате setIntent(intent) вътре в onNewIntent() за актуализиране на Intent.

Пример за използване на launchMode="singleTop" и onNewIntent():

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

В класа YourDeeplinkActivity:

class YourDeeplinkActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_deeplink)
        // Начална обработка, ако активността се създава
        handleIntent(intent)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        // Важно е да актуализирате Intent за getIntent()
        setIntent(intent)
        // Обработка на новия Intent (deeplink)
        handleIntent(intent)
    }

    private fun handleIntent(intent: Intent?) {
        intent?.data?.let { uri ->
            // Логика за обработка на URI на deeplink
            Log.d("DeeplinkActivity", "Received deeplink: $uri")
            // Например, извличане на параметри и навигация към съответния фрагмент
        }
    }
}

Изборът на подход зависи от конкретния сценарий на използване и желаното поведение на стека активности. Най-често използваното решение за deeplink-ове, които водят към вече съществуваща активност, е използването на launchMode="singleTop" и обработката в onNewIntent().