控制/指定Android Jetpack Navigation deeplink主机名

控制/指定Android Jetpack Navigation deeplink主机名,android,android-jetpack,android-architecture-navigation,Android,Android Jetpack,Android Architecture Navigation,通过Jetpack导航库(在编写本文时为Ver2.1.0-alpha03),构造deeplink URI允许将应用程序包名替换为${applicationId}(它使用上下文.getPackageName()) 通过使用导航库,可以为您创建意图过滤器 在Jetpack之前,资源可以设置导航意图过滤器。例如: 我目前正在开发一个白标签应用程序,其中包名=深度链接主机名 如果不在一系列样式中重新定义所有导航图,我可以指定深度链接主机名吗?Jetpack导航库允许您创建或定义自己的图以及目的地

通过Jetpack导航库(在编写本文时为Ver
2.1.0-alpha03
),构造deeplink URI允许将应用程序包名替换为
${applicationId}
(它使用
上下文.getPackageName()


通过使用导航库,可以为您创建意图过滤器

在Jetpack之前,资源可以设置导航意图过滤器。例如:


我目前正在开发一个白标签应用程序,其中
包名
=
深度链接主机名


如果不在一系列样式中重新定义所有导航图,我可以指定深度链接主机名吗?

Jetpack导航库允许您创建或定义自己的图以及目的地,但使用导航的一个重要原因是要处理深度链接,让导航库将导航回栈构建到条目目标

Jetpack使用Gradle任务将导航图中的deeplink URL转换为清单中的意图过滤器。XML导航图也会在运行时读取,以创建带有相应deeplink条目的导航图

这可以通过创建一个gradle任务来解决,该任务用gradle prameter或默认值替换令牌

添加新的gradle文件
navigation.gradle.kts

import java.io.BufferedReader

tasks.register("convertNavigation") {
    doLast{
        val appIntentHost: String by project

        val MAGIC_TEXT = "{@string/app_intent_host}"
        val DEFAULT_URL = "default.url.com"

        val generatedResDir = File(buildDir, "generated/local/main/res")
        val targetDir = File(  generatedResDir, "navigation")

        if (targetDir.exists()) {
            targetDir.delete()
        }
        targetDir.mkdirs()

        val tree = fileTree("src/main/nav/navigation")
        val host: String = if (project.hasProperty("appIntentHost") && !appIntentHost.isBlank())
            appIntentHost else DEFAULT_URL

        println ("Replacing $MAGIC_TEXT in nav files with [$host]")

        for (f in tree) {
            val target = File(targetDir, f.name)
            println ("Transforming ${f.name} to ${target.absolutePath}")
            val writer = target.writer()
            val allText = f.absoluteFile.inputStream().bufferedReader().use(BufferedReader::readText)

            writer.write(allText.replace(MAGIC_TEXT, host))
            writer.close()
        }
    }
}
将此添加到您拥有导航功能的应用程序/模块的
build.gradle

apply from: "navigation.gradle.kts"

gradle.projectsEvaluated {
  // Modifies and copies asset nav graphs to generated
  preBuild.dependsOn convertNavigation
}

android{
  sourceSets {
    //Location of generate navigation XML
    main.assets.srcDirs += 'src/main/nav'
  }
}
将导航xml移动到
src/main/nav/navigation
(例如
MyApplication/app/src/main/nav/navigation
)并使deeplinks如下所示

        <deepLink android:id="@+id/verify_link"
            app:uri="https://{@string/app_intent_host}/verify/" />

这将生成正确的清单
default.url.com
作为url,除非您使用
-pappinenthost=customer.url.com
运行gradle脚本,在这种情况下,该脚本将被替代


希望谷歌能解决这个问题(我不知道开源的gradle脚本在哪里实现了这一点),这在将来将成为一个无效的答案

如果遵循此答案,您仍然可以在AS中使用导航编辑器。修改后的导航显示在
项目/res/navigation
下,但在重建时将被覆盖。因此,在那里进行更改,然后将文本版本放入剪贴板,查看
项目/资产/导航
复制并右键单击->与剪贴板比较,然后在中复制更改。