这一次,我需要你的帮助关于使用Android导航组件与深度链接。
我一直在关注这个文档,fragment和deeplink之间的连接工作正常。
这个问题是关于接收深度链接的活动的。在我的例子中,我设置了android: LaunchMode="单项任务"
<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每次单击deeplink都会收到两次onNewIntent呼叫。有时甚至会创建新的活动实例。。喜欢
1_uu对象1 onNewIntent
2_uu对象1 onNewIntent
3_uu2onCreate
这里有一些日志:
首次发射
onCreate:Intent{flg=0x10000000 cmp={applicationId}/{package}。WelcomeActivity}与活动:{package}。WelcomeActivity@4adbef0
开放深度链接
onNewIntent:Intent{act=android.Intent.action.VIEW cat=[android.Intent.category.BROWSABLE]dat=https://{depp_link}…flg=0x10010000 cmp={applicationId}/{package}。WelcomeActivity(有额外功能)}与活动:{package}。WelcomeActivity@4adbef0
onNewIntent:Intent{act=android.Intent.action.VIEW cat=[android.Intent.category.BROWSABLE]dat=https://{depp_link}。。。flg=0x1001c000 cmp={applicationId}/{package}。WelcomeActivity(有额外功能)}与活动:{package}。WelcomeActivity@4adbef0
在创建:意图{act=android.intent.action.VIEW cat=[android.intent.category.BROWSABLE]dat=https://{depp_link}... flg=0x1001c000 cmp={应用ID}/{包}。欢迎活动(有额外功能)}带活动:{包}.WelcomeActivity@b77c6b
关闭应用程序并打开深层链接
onCreate:Intent{act=android.Intent.action.VIEW cat=[android.Intent.category.BROWSABLE]dat=https://{depp_link}。。。flg=0x10018000 cmp={applicationId}/{package}。WelcomeActivity(有额外功能)}与活动:{package}。WelcomeActivity@b78f4df
onNewIntent: Intent{act=android.intent.action.VIEW cat=[android.intent.category.浏览]dat=https://{depp_link}... flg=0x1001c000 cmp={应用ID}/{包}。欢迎活动(有额外功能)}带活动:{包}.WelcomeActivity@b78f4df
在创建:意图{act=android.intent.action.VIEW cat=[android.intent.category.BROWSABLE]dat=https://{depp_link}... flg=0x1001c000 cmp={应用程序id}/{包}。欢迎活动(有额外功能)}带{包}.WelcomeActivity@dfe87b2
更新:
1-似乎启动模式与此问题无关。我注意到默认启动模式也是如此。
2-导航控制器。导航(intent.dataString.toUri())似乎工作正常。所以我想问题在于导航控制器。handleDeepLink(意图)。
匿名用户
当一个隐式的深层链接被点击时,FLAG_ACTIVITY_NEW_TASK
被有意地设置。并且根据留档,后栈将被重新创建到一个良好的状态。请参见这里的留档隐式深层链接。
如果您不想要这种行为,也不想更改意图标志,您可以自己处理深度链接,而不是将其传递给导航组件。因此,如果您使用的是AdvancedNavigationSample,您需要删除handle深度链接
,并使用findNavController()。导航()
指向方向。
另外,请记住,将启动器活动的启动模式设置为Single任务
,以便在单击深度链接或通知时接收新意图。
- 更换导航控制器。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中。数据
在PendingEvent中
- 您可以根据需要验证和更改deeplink。如用户未登录,则直接进入登录活动或移动到指定目的地
当onNewIntent上的callback第一次到达时,只需设置标志intent即可。添加标志(意图、标志、活动、清除任务)
并将突变的意图传递给
handleDeepLink(意图)
由于重新连接到现有的
活动
(将backbackback trace完全重建到所需的深度链接目的地),而不是启动新的活动,此标志消除了第二次到达的
onNewIntent
回调。
详细信息请参见
handleDeepLink
方法的源代码。
通过测试不同的变化,我得出结论,“navController.handleDeepLink(intent)”导致了这种奇怪的行为。
这就是我尝试的:
我从导航中删除了深层链接,深层链接工作得很好(我手动添加了深层链接),行为很正常:使用单一任务,如果活动已经创建,那么onNewIntent只被调用一次。如果活动没有创建,那么onCreate被调用。
另外一个问题是,navController.handleDeepLink(意图)将在onCreate中自动调用(您可以在javadocs中检查)。当调用onNewIntent时,您需要调用navController.handleDeepLink(意图)。
我决定尝试NavController的“导航(Uri深度链接)”,我看到这是按预期工作的(第一段中描述的行为)。有了这个替代方法,我决定做一些改变:
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(intent)”,因为如果存在该信息,就会自动调用它,从而导致奇怪的行为。
导航控制器。图表hasDeepLink(uri)将帮助您查看图形是否可以处理该uri。如果不使用它,则“导航(Uri deepLink)”将引发异常。
如果你遇到同样的问题,希望它能帮助你。如果你对此有更多的见解,请随时发表评论。
当我从deeplink(用户点击URL)打开应用程序并按下后退按钮时,我希望用户导航到我导航图中的前一个片段,但它只是退出应用程序。 文件中说,反向导航的工作方式应该与用户自然到达屏幕的方式相同。 我可以在导航图中指定所需的backbackback吗?或者可以在deeplink后自动形成Backback?对于旧版本的库,我发现在按back press键后,它应该导航到导航图的根目录,但事实并非如此
如果我打开在桌面浏览器上收到的电子邮件中的链接,则用户的电子邮件被成功验证(标志FirebaseUser.isemailVerificed返回true) 然而,我尝试使用深度链接。因此,如果用户点击移动设备上的链接,将在应用程序中重定向,我有深度链接监听器。我希望当我收到应用程序内的深度链接数据时,isemailverificed标志会立即更新,但事实并非如此)。实际上,即使在按下链接时,也应该进
TL;DR:与Spotify iPad应用程序类似的具有深度导航功能的多窗格应用程序应该如何在Android上看起来和工作,以及如何实现这一点? 在模型中,用户看到一个初始概览,然后从第一个列表中选择“项目#2”。一个新的活动开始了,向他展示了项目2的详细信息。在这里,他选择查看与项目#2相关的事物的列表。第三张图片中的新openend活动显示了这个列表,点击其中一个就会打开这个东西的详细信息。他
我正在一个新的Android应用程序上使用导航组件,但我不知道怎么做 首先,我有我的主活动,我有main_navigation_graph 主要活动 NavHostFragment main_navigation_graph里面有3个碎片 这里一切都很好。问题是当我到达最后一个片段时,因为在这个片段上,我想根据BottomNavigationView输入(暂时)显示一些子片段(在新的NavHost
我正在实现Android深度链接的概念,它工作正常,我的问题是,如果应用程序没有安装在手机上,我想将链接重定向到我的play store应用程序页面。 请引导我找到它,谢谢。
viewmodel随活动或其所连接的片段而生或死。这产生了某些后果,我无法理解为什么没有人询问(如果我们将导航架构融入图片中)。 根据最新的android博客和导航框架的工作方式,建议我们进入单活动多片段诗句。 假设我有以下应用程序设计。 现在,由于我使用共享视图模型,这意味着我的视图模型将附加到活动。然而,这似乎是泄漏的。就像如果我从A到E一路遍历,现在回来弹出片段到片段B,视图模型CDE应该被