web-dev-qa-db-fra.com

Android Composants de navigation avec lien profond: OnNewIntent appelé plusieurs fois

Cette fois, j'ai besoin de votre aide concernant l'utilisation de Android Composants de navigation avec DEEPLINK.

Je suis en train de suivre cela Documentation et la connexion entre fragment et Deeplink fonctionne bien.

Le problème vient en ce qui concerne l'activité qui reçoit le DEEPLINK. Dans mon cas, j'ai défini l'Android: LaunleMode = "singleask"

<activity Android:name=".features.welcome.WelcomeActivity"
    Android:launchMode="singleTask">
     <nav-graph Android:value="@navigation/welcome_nav_graph" />
</activity>

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    Timber.d("onNewIntent: $intent with activity: $this")
    navController.handleDeepLink(intent)
}

Avec cette configuration, j'ai remarqué quelques comportements étranges:

La bienvenue accueille surNemer à deux reprises à chaque fois que je clique sur le DEEPLINK. Avoir même parfois de nouvelles instances de cette activité créée .. comme

1_ objet1-onNewInter

2_ objet1-onNewInter

3_ objet2-oncreate

Ici vous avez des journaux:

Premier lancement

oncreate: Intention {FLG = 0x10000000 CMP = {Applicationd}/{Paquet} .welcomactivité} Avec Activité: {PackageOr.welcomActivity@4Adbef0

Ouvrir une liaison profonde

surNewintent: intention {act = android.inTent.action.view cat = [Android.inTent.category.Browstable] DAT = https: // {DEPP_LINK} ... FLG = 0x10010000 CMP = {ApplicationD}/{Paquet} .welcectivity (a Extras)} Avec Activité: {Package}.welcomCittivity@4Adbef0

onNewIntent: Intention {act = Android.Intent.Action.View Cat = [Android.inTent.category.Browsable] DAT = https: // {DEPP_LINK} ... Flg = 0x1001C000 CMP = {ApplicationD}/{Paquet} .welcectivity (a des extras)} avec l'activité: {PackageOs.welcomsactivity@4Adbef0

oncreate: Intention {act = Android.Intent.Action.View Cat = [Android.Intent.Category.Browsable] DAT = https: // {DEPP_LINK} ... FLG = 0x1001C000 CMP = {ApplicationD}/{Paquet} .welcectivity (a des extras)} avec l'activité: {Package}.welcomEActivity@b77c6b

Tuer l'application et ouvrir une liaison profonde

oncreate: Intention {act = Android.Intent.Action.View Cat = [Android.inTent.Category.Browsable] DAT = https: // {DEPP_LINK} ... FLG = 0x10018000 CMP = {ApplicationD}/{Paquet} .welcectivity (a des extras)} avec activité: {Package}.welcomActivity@b78f4df

onNewIntent: Intention {act = Android.Intent.Action.View Cat = [Android.inTent.category.Browsable] DAT = https: // {DEPP_LINK} ... Flg = 0x1001C000 CMP = {ApplicationD}/{Paquet} .welcectivity (a des extras)} avec activité: {Package}.welcomActivity@b78f4df

oncreate: Intention {act = Android.Intent.Action.View Cat = [Android.Intent.Category.Browsable] DAT = https: // {DEPP_LINK} ... FLG = 0x1001C000 CMP = {ApplicationD}/{Paquet} .welcectivity (a des extras)} avec {Package}.welcomcivity@dfe87b2

METTRE À JOUR:

1 -Il semble que le mode de lancement n'a rien à voir avec ce problème. J'ai remarqué la même chose avec le mode de lancement par défaut.

2- NavController.navigater (intention.datatring.Touri ()) semble fonctionner correctement. Donc, je suppose que le problème est NavController.HandleDeeeplink (Intention).

6
Leandro Ocampo

Il se sent bizarre, mais cela semble en fait fonctionner comme prévu. la documentation concernant les liens profonds implicites indique:

Lors du déclenchement d'une liaison profonde implicite, l'état de la pile arrière dépend de la question de savoir si l'intention implicite a été lancée avec l'intention.flag_activity_New_Task Drapeau:

Si le drapeau est défini, la pile arrière de la tâche est effacée et remplacée par la destination de lien profonde ....

Si le drapeau n'est pas défini, vous restez sur la pile de tâches de l'application précédente où la liaison profonde implicite a été déclenchée.

Dans votre cas, je crois que lorsque vous appuyez sur un lien, l'intention a le drapeau Intent.FLAG_ACTIVITY_NEW_TASK Ensemble, la toute nouvelle pile est créée. Actuellement la mise en œuvre Il suffit de redémarrer l'activité avec la pile nouvellement créée pour vous assurer que l'état de la tâche est cohérent.

Si vous n'avez pas besoin de ce comportement, une solution de contournement possible serait d'effacer le drapeau Intent.FLAG_ACTIVITY_NEW_TASK À partir de l'intention avant que la composante de navigation ait une chance de le gérer.

0
esentsov

J'ai subi un problème similaire et je suivais NavigationAvancedsample où j'avais BottomNavigationView avec plusieurs NavHostFragments. Donc, poster mon correctif pour ceux qui ont le même cas.

Plus précisément, onCreate() de ma maacalisation était appelée deux fois lorsque l'application a été lancée via une notification Deville.

J'avais suivi des drapeaux fixés pour l'intention:

private fun getPendingIntent(data: Uri?): PendingIntent {
    val intent = Intent(context, MainActivity::class.Java)
    intent.action = Intent.ACTION_VIEW
    intent.data = data
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
    return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT)
}

Et je n'avais pas Android:launchMode="singleTask" Dans le manifeste de la MainAlactivité, car ce n'était pas vraiment utile dans mon cas.

J'ai résolu mon problème d'abord empêcher navController.handleDeepLink(intent) _ à appeler automatiquement sur onCreate() de la MainActivité avec le code suivant (grâce à vous):

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val uri = intent.data
    intent.data = null
}

puis en faisant le changement dans ce PR dans le fichier NavigationExtensions qui remplace essentiellement navController.handleDeepLink(intent) avec navController.navigate(uri) qui faisait la création de l'activité deux fois comme vous l'avez noté dans votre message.

Donc, le code de configuration de la navigation avec BottomNavigationView semble comme suit dans la MainActivity:

private fun setupBottomNavigation(uri: Uri?) {
    val navGraphIds =
        listOf(
            R.navigation.all_integrations,
            R.navigation.favourites,
            R.navigation.settings
        )

    currentNavController = bottomNavView.setupWithNavController(
        navGraphIds,
        supportFragmentManager,
        R.id.navHostContainer
    )

    uri?.let {
        bottomNavView.handleDeepLinks(
            navGraphIds,
            supportFragmentManager,
            R.id.navHostContainer,
            it
        )
    }
}
0
Nijat Ahmadli