Sobes.tech
Middle

Como lidar com a situação quando a atividade é aberta várias vezes devido a um deeplink?

sobes.tech IA

Resposta da IA

Existem várias abordagens:

  1. Uso de flags no Intent:

    • FLAG_ACTIVITY_SINGLE_TOP: Se a atividade já estiver no topo da pilha, o método onNewIntent() será chamado em vez de criar uma nova instância.
    • FLAG_ACTIVITY_CLEAR_TOP: Se a atividade já existir na pilha, todas as atividades acima dela serão finalizadas e ela será trazida para o topo.
    • Em combinação com FLAG_ACTIVITY_NEW_TASK: Frequentemente usado com CLEAR_TOP para trabalhar com atividades de outra tarefa.
  2. Configuração do launchMode no AndroidManifest.xml:

    • singleTop: Semelhante a FLAG_ACTIVITY_SINGLE_TOP ao lançar via Intent.
    • singleTask: A atividade é a raiz de uma nova tarefa; se uma instância já existir em alguma tarefa, ela será trazida para frente, e todas as atividades acima dela serão finalizadas.
    • singleInstance: A atividade existe na sua própria tarefa e é a única atividade nessa tarefa.
  3. Verificação da existência da atividade antes de lançá-la:

    • Use ActivityManager para verificar a pilha atual de atividades. Essa abordagem é menos preferida devido à sua complexidade e custos.
  4. Resposta ao onNewIntent():

    • Quando usar singleTop ou FLAG_ACTIVITY_SINGLE_TOP, toda a lógica de manipulação do deeplink deve ser implementada em onNewIntent(), não em onCreate(). Não se esqueça de chamar setIntent(intent) dentro de onNewIntent() para atualizar o Intent acessível via getIntent().

Exemplo de uso de launchMode="singleTop" e onNewIntent():

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

Na classe da atividade YourDeeplinkActivity:

class YourDeeplinkActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_deeplink)
        // Processamento inicial, se a atividade for criada
        handleIntent(intent)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        // É importante atualizar o Intent para getIntent()
        setIntent(intent)
        // Processar o novo Intent (deeplink)
        handleIntent(intent)
    }

    private fun handleIntent(intent: Intent?) {
        intent?.data?.let { uri ->
            // Lógica de processamento do URI do deeplink
            Log.d("DeeplinkActivity", "Deeplink recebido: $uri")
            // Por exemplo, extrair parâmetros e navegar para o fragmento desejado
        }
    }
}

A escolha da abordagem depende do cenário específico e do comportamento desejado na pilha de atividades. A solução mais comum para deeplinks que levam a uma atividade já existente é usar launchMode="singleTop" e tratar em onNewIntent().