Sobes.tech
Middle

¿Cómo manejar la situación cuando la actividad se abre varias veces debido a un deeplink?

sobes.tech AI

Respuesta de la IA

Existen varios enfoques:

  1. Uso de banderas en Intent:

    • FLAG_ACTIVITY_SINGLE_TOP: Si la actividad ya está en la parte superior de la pila, en lugar de crear una nueva instancia se llamará al método onNewIntent().
    • FLAG_ACTIVITY_CLEAR_TOP: Si la actividad ya existe en la pila, todas las actividades por encima de ella serán finalizadas y será llevada a la posición superior.
    • En combinación con FLAG_ACTIVITY_NEW_TASK: Se usa a menudo con CLEAR_TOP para trabajar con actividades de otra tarea.
  2. Configuración de launchMode en AndroidManifest.xml:

    • singleTop: Similar a FLAG_ACTIVITY_SINGLE_TOP al lanzar mediante Intent.
    • singleTask: La actividad es la raíz de una nueva tarea; si ya existe una instancia en alguna tarea, será traída al frente y todas las actividades por encima de ella serán finalizadas.
    • singleInstance: La actividad existe en su propia tarea y es la única actividad en esa tarea.
  3. Verificación de existencia de la actividad antes de lanzarla:

    • Usa ActivityManager para verificar la pila actual de actividades. Este método es menos preferido debido a su complejidad y costos.
  4. Respuesta a onNewIntent():

    • Cuando se usa singleTop o FLAG_ACTIVITY_SINGLE_TOP, toda la lógica de manejo del deeplink debe implementarse en onNewIntent(), no en onCreate(). No olvides llamar a setIntent(intent) dentro de onNewIntent() para actualizar el Intent accesible mediante getIntent().

Ejemplo de uso de launchMode="singleTop" y onNewIntent():

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

En la clase de la actividad YourDeeplinkActivity:

class YourDeeplinkActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_deeplink)
        // Procesamiento inicial si la actividad se crea
        handleIntent(intent)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        // Es importante actualizar el Intent para getIntent()
        setIntent(intent)
        // Procesar el nuevo Intent (deeplink)
        handleIntent(intent)
    }

    private fun handleIntent(intent: Intent?) {
        intent?.data?.let { uri ->
            // Lógica para procesar el URI del deeplink
            Log.d("DeeplinkActivity", "Deeplink recibido: $uri")
            // Por ejemplo, extraer parámetros y navegar al fragmento correspondiente
        }
    }
}

La elección del método depende del escenario específico y del comportamiento deseado en la pila de actividades. La solución más común para deeplinks que llevan a una actividad ya existente es usar launchMode="singleTop" y manejarlo en onNewIntent().