Middle
How to handle a situation where activity opens multiple times due to deeplink?
sobes.tech AI
Answer from AI
There are several approaches:
-
Using flags in Intent:
FLAG_ACTIVITY_SINGLE_TOP: If the activity is already at the top of the stack, theonNewIntent()method will be called instead of creating a new instance.FLAG_ACTIVITY_CLEAR_TOP: If the activity already exists in the stack, all activities above it will be finished, and it will be brought to the top.- In combination with
FLAG_ACTIVITY_NEW_TASK: Often used withCLEAR_TOPfor working with activities from another task.
-
Configuring
launchModein AndroidManifest.xml:singleTop: Similar toFLAG_ACTIVITY_SINGLE_TOPwhen launching viaIntent.singleTask: The activity is the root of a new task; if an instance already exists in some task, it will be brought to the front, and all activities above it will be finished.singleInstance: The activity exists in its own task and is the only activity in that task.
-
Checking for activity existence before launching:
- Use
ActivityManagerto check the current activity stack. This approach is less preferred due to complexity and overhead.
- Use
-
Reacting to
onNewIntent():- When using
singleToporFLAG_ACTIVITY_SINGLE_TOP, all deeplink processing logic should be implemented in theonNewIntent()method, not inonCreate(). Remember to callsetIntent(intent)insideonNewIntent()to update the Intent accessible viagetIntent().
- When using
Example of using launchMode="singleTop" and onNewIntent():
In 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>
In the activity class YourDeeplinkActivity:
class YourDeeplinkActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_deeplink)
// Initial processing if activity is created
handleIntent(intent)
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
// Important to update the Intent for getIntent()
setIntent(intent)
// Handle new Intent (deeplink)
handleIntent(intent)
}
private fun handleIntent(intent: Intent?) {
intent?.data?.let { uri ->
// Logic to process the deeplink URI
Log.d("DeeplinkActivity", "Received deeplink: $uri")
// For example, extract parameters and navigate to the appropriate fragment
}
}
}
The choice of approach depends on the specific use case and desired activity stack behavior. The most common solution for deeplinks leading to an existing activity is to use launchMode="singleTop" and handle it in onNewIntent().