这一次,我需要您的帮助,在使用android导航组件与深度链接。
我一直在跟踪这个文档,片段和深度链接之间的连接工作得很好。
问题来自于接收深度链接的活动。在我的例子中,我设置了android:launchMode="singleTask“
<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)
}
通过这种配置,我注意到了一些奇怪的行为:
每次单击深度链接时,WelcomeActivity都会收到两次onNewIntent调用。甚至有时还创建了新的活动实例。喜欢
1_对象1-onNewIntent
2_对象1-onNewIntent
3_ object2-onCreate
这里有一些日志:
第一次发射 onCreate:意图{ flg=0x10000000 cmp={applicationId}/{package}.WelcomeActivity }具有活动:{package}.WelcomeActivity@4adbef0 开深链 onNewIntent: act=android.intent.action.VIEW {act=android.intent.action.VIEW cat=android.intent.category.BROWSABLE dat=链接)… flg=0x10010000 cmp={applicationId}/{package}.WelcomeActivity (已附加)}与活动:{package}.WelcomeActivity@4adbef0 onNewIntent:意图{ act=android.intent.action.VIEW cat=android.intent.category.BROWSABLE dat=链接}..。.具有活动的flg=0x1001c000 cmp={applicationId}/{package}.WelcomeActivity (有额外的)}:{applicationId}.WelcomeActivity@4adbef0 onCreate:意图{ act=android.intent.action.VIEW cat=android.intent.category.BROWSABLE dat=链接}..。.具有活动的flg=0x1001c000 cmp={applicationId}/{package}.WelcomeActivity (有额外的)}:{applicationId}.WelcomeActivity@b77c6b 关闭应用程序并打开深度链接 onCreate:意图{ act=android.intent.action.VIEW cat=android.intent.category.BROWSABLE dat=链接}..。.具有活动的flg=0x10018000 cmp={applicationId}/{package}.WelcomeActivity (有额外的)}:{applicationId}.WelcomeActivity@b78f4df onNewIntent:意图{ act=android.intent.action.VIEW cat=android.intent.category.BROWSABLE dat=链接}..。.具有活动的flg=0x1001c000 cmp={applicationId}/{package}.WelcomeActivity (有额外的)}:{applicationId}.WelcomeActivity@b78f4df onCreate:意图{ act=android.intent.action.VIEW cat=android.intent.category.BROWSABLE dat=链接}..。.flg=0x1001c000 cmp={applicationId}/{package}.WelcomeActivity (有附加)}和{package}.WelcomeActivity@dfe87b2
更新:
1 -It似乎与这个问题无关。我注意到默认启动模式也是如此。
2- navController.navigate(intent.dataString.toUri())似乎运行良好。所以我想问题是navController.handleDeepLink(意图)。
发布于 2020-08-06 23:00:48
当onNewIntent
上的回调第一次到达时,只需设置标志intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
并将突变的意图传递给handleDeepLink(intent);
此标志消除了onNewIntent
回调的第二次到达,原因是重新连接到现有的Activity
(完全重构到所需的深度链接目的地的后台跟踪),而不是启动新的Activity
。
详细信息在handleDeepLink
方法的源代码中。
发布于 2020-05-22 05:42:59
通过测试不同的更改,我得出的结论是,“navController.handleDeepLink(意图)”是导致这种奇怪行为的原因。
这就是我试过的:
我从导航中删除了deepLink,深层链接正常工作(我手动添加了deepLink ):使用singleTask,如果活动已经创建,那么onNewIntent只会被调用一次。如果未创建活动,则调用onCreate。
这方面的另一个问题是,navController.handleDeepLink(意图)将在onCreate中自动调用(您可以在javadocs中检查它)。当调用onNewIntent时,您需要调用navController.handleDeepLink(意图)。
我决定尝试“导航(Uri deepLink)”从NavController,我看到这是正常工作(在第一段中描述的行为)。有了这个替代方法,我决定做一些修改:
class WelcomeActivity : AppCompatActivity(){
private val navController by lazy { findNavController(R.id.nav_host_fragment) }
private var deepLinkData: Uri? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Timber.d("onCreate: $intent with activity: $this")
val data = intent.data
intent.data = null
setContentView(R.layout.activity_welcome)
handleDeepLink(data)
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
Timber.d("onNewIntent: $intent with activity: $this")
setIntent(intent)
val data = intent?.data
handleDeepLink(data)
}
private fun handleDeepLink(uri: Uri?) {
//TODO: there is an issue that will cause onNewIntent to be called twice when the activity is already present.
if (uri != null && deepLinkData.toString() != uri.toString() && navController.graph.hasDeepLink(uri)) {
//possible deep link for LoginFragment
deepLinkData = uri
navController.navigate(uri)
}
}
}
注意onCreate中的这个代码块是很重要的:
val data = intent.data
intent.data = null
这样做的原因是,如果我需要阻止“navController.handleDeepLink(意图)”被调用,因为如果存在该信息,就会自动调用它,从而导致这种奇怪的行为。
navController.graph.hasDeepLink( uri )将帮助您查看您的图形是否能够处理那个uri。如果您不使用它,那么“导航(Uri deepLink)”将引发异常。
如果你遇到同样的问题,希望它能帮助你。如果你对此有更多的见解,请留下一些评论。
发布于 2020-07-27 03:52:53
当单击隐式深度链接时,就会有意图地设置FLAG_ACTIVITY_NEW_TASK
。并且,根据文档,将重新创建后台,使其处于良好状态。请参阅这里的文档隐式深链。
如果您不想要这种行为,并且不想更改意图标志,您可以自己处理深度链接,而不是将它传递给导航组件。因此,如果您使用的是AdvancedNavigationSample,您需要删除handledeeplink
并按照方向使用findNavController().navigate()
。
另外,请记住将launcher活动的启动模式设置为singleTask
,以便在单击“深度链接”或“通知”时接收新的意图。
NavController.handledeeplink()
替换为fun BottomNavigationView.navigateDeeplink(
navGraphIds: List<Int>,
fragmentManager: FragmentManager,
containerId: Int,
uri: Uri
) {
navGraphIds.forEachIndexed { index, navGraphId ->
val fragmentTag = getFragmentTag(index)
// Find or create the Navigation host fragment
val navHostFragment = obtainNavHostFragment(
fragmentManager,
fragmentTag,
navGraphId,
containerId
)
// Handle deeplink
val canHandleDeeplink = navHostFragment.navController.graph.hasDeepLink(uri)
if (canHandleDeeplink) {
if (selectedItemId != navHostFragment.navController.graph.id) {
selectedItemId = navHostFragment.navController.graph.id
}
navHostFragment.lifecycleScope.launchWhenResumed {
// Wait for fragment to restore state from backStack
// otherwise navigate will be ignored
// Ignoring navigate() call: FragmentManager has already saved its state
navHostFragment.navController.navigateOnce(uri)
}
}
}
}
intent.data
存储在变量中,并将其设置为null,这样导航组件就无法处理它。在onHandleNewIntent
中也做同样的事情完整的解决方案是在这个示例上实现的。
优点:
intent.data
中PendingIntent中传递它。https://stackoverflow.com/questions/61951850
复制相似问题