deeplink_在Android编译时生成DeepLink

本文介绍了如何在Android应用中动态生成DeepLink,通过 Deeplink 可以实现应用程序间的深度链接,提高用户体验。翻译自一篇Medium文章,详细解析了在编译时创建DeepLink的步骤和技术要点。
摘要由CSDN通过智能技术生成

deeplink

Deeplinks are important aspects of the app which makes our app accessible using certain links and push notifications and are generally key to the company’s marketing strategy.It is vital in connecting our web ecosystem with that of application’s.

深层链接是应用程序的重要方面,它使我们的应用程序可以使用某些链接和推送通知进行访问,并且通常是公司营销策略的关键。对于将我们的网络生态系统与应用程序的网络生态联系起来,至关重要。

让我们解决这个问题 (Let's Address the problem)

As your app keeps on growing so does deeplinks based on your market requirements. when it comes to our java/kotlin classes we tend to follow various principles (SOLID etc) to keep code separated and to prevent our classes from becoming so-called “GOD” class but what about your manifest?

随着您的应用程序不断增长,基于您的市场需求的深层链接也会不断增长。 当涉及到我们的java / kotlin类时,我们倾向于遵循各种原理(SOLID等)以使代码分开并防止我们的类成为所谓的“ GOD”类,但是您的清单呢?

To address the Problem consider your app supports a single deeplink for that particular deep link you would have to cater to both HTTP and HTTPS schemes in order to successfully upload your apk to the play store.

要解决该问题,请考虑您的应用为该特定深层链接支持单个深层链接,您必须同时满足HTTP和HTTPS方案,才能成功将apk上传到Play商店。

<data
android:host="www.xyz.xyz"
android:pathPrefix="/home"
android:scheme="http"
/>
<data
android:host="www.xyz.xyz"
android:pathPrefix="/home"
android:scheme="https"
/>

No Problem, Not bad so far… we will put two <data> entries for our path and we are done easy enough.

没问题,到目前为止还算不错……我们将在路径中放置两个<data>条目,并且操作起来很容易。

But one fine day your company decides to launch globally to let's say 4 more countries and support 4 different languages (with a localized path like {locale}/home/) now that would be a problem, Come to think of it you will have to add 2*4*4 ie, 32 <data> entries for a single pathPrefix and this is just an example, Paths can easily increase the number of </data> entries depending on the structure of the path itself which can variate from case to case. 🤕

但是,有一天,您的公司决定在全球范围内推出更多的国家/地区,并支持4种不同的语言 (使用{locale}/home/的本地化路径) 现在这将成为一个问题,想一想,您将必须为单个pathPrefix添加2 * 4 * 4,即32个 <data>条目,这仅是示例,Paths可以轻松增加</data>的数量</data>条目取决于路径本身的结构,该结构可能因情况而异。 🤕

现在怎么办? (What Now?)

As we know domains, locale or whatever that leads to new </data> entry beforehand, So let’s try and come up with a script that takes the path and makes the </data> entry in the manifest for us.

我们知道域,语言环境或任何会导致新</data>条目的内容,所以让我们尝试提出一个脚本,该脚本采用路径并在清单中创建</data>条目。

了解生成的清单文件 (Understanding generated Manifest file)

It is absolutely important to keep in mind that the generated manifest file is different for both APK and Bundle.

请务必牢记,APK和Bundle生成的清单文件是不同的。

Image for post

给我看看代码! (Show me the code!!)

  1. Create a separate Gradle file for keeping your deeplink configurations. let's say deeplink_config.gradle’.

    创建一个单独的Gradle文件以保留您的Deeplink配置。 我们说 deeplink_config.gradle ”。

  2. Add the following to your build.gradle file

    将以下内容添加到您的build.gradle文件中

apply from: 'deeplink_config.gradle'

3. Add a variable in the manifest file which will be replaced by </data> tags inside your intent-filter.

3.在清单文件中添加一个变量,该变量将由intent-filter </data>标签替换。

<intent-filter
android:autoVerify="true"
tools:ignore="AppLinkUrlError"
>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
deepLinkPlaceholder
</intent-filter>

4. Add code to deeplink_config to generate </data> for bothHTTP and HTTPS scheme.

4.将代码添加到deeplink_config HTTPHTTPS方案生成</data>

ext {
        listOfDeepLinkUrls = new ArrayList<String>()
        listOfDeepLinkUrls.add("/home")
       
        locales = ["en", "ar","es","hi-IN"]
    }
    
ext.generateData = { host, listOfDeepLinkUrls, locales,listOfDomains ->
        String links = ""
        listOfDeepLinkUrls.each{ item ->
                links += data(item,host)
                locales.each{ locale ->
                        listOfDomains.each { domain ->
                                links += data("/"+locale.replace("_","-")+item,domain)
                        }
                }
        }
        return links
}


static def data(String path, String host) {
        return http(path,host) + https(path,host)
}


static def http(String path, String host) {
        return "\n" +
                "               <data\n" +
                "                   android:host=\"$host\"\n" +
                "                   android:pathPrefix=\"$path\"\n" +
                "                   android:scheme=\"http\"/>\n"
}


static def https(String path, String host) {
        return "\n" +
                "               <data\n" +
                "                   android:host=\"$host\"\n" +
                "                   android:pathPrefix=\"$path\"\n" +
                "                   android:scheme=\"https\"/>\n"
}

generateData method takes in your host, listOfDeepLinkUrls, locales (depends on your use case) and list of domains ex: [“www.xyz.in"].

generateData方法接收hostlistOfDeepLinkUrlslocales (取决于您的用例)和list of domains例如:[ “ www.xyz.in” ]。

where listOfDeepLinkUrls is storing all our pathsPrefixes. So, to add a new deeplink to your application you just need to add it to the list rather than adding multiple <data> manually inside the manifest.

其中listOfDeepLinkUrls存储我们所有的pathsPrefixes. 因此,要将新的深层链接添加到您的应用程序,只需要将其添加到列表中,而不是在manifest手动添加多个<data>

5. Write these generated <data> to your apk and bundle generated manifest files as discussed earlier apk and bundle both have their separate manifest files and to write to those we would need a path to these generated files.

5.将这些生成的<data>写入您的apk,然后将这些生成的清单文件写到您的apk中,如前所述,apk和bundle都有各自的清单文件,要写入这些文件,我们需要这些生成文件的路径。

manifestOutputDirectory can be used directly for getting the path to Apk’s manifest file but I was not able to find one for bundles so let's utilize manifestOutputDirectory to extract path of bundle’s manifest file.

manifestOutputDirectory可以直接用于获取Apk清单文件的路径,但是我无法为bundle找到一个,因此让我们利用manifestOutputDirectory提取捆绑清单文件的路径。

android.applicationVariants.all { variant ->
        variant.outputs.all { output ->
                output.processManifest.doLast {
                        def placeholders = variant.mergedFlavor.manifestPlaceholders;
                        if (placeholders == null || placeholders.isEmpty()) {
                                return
                        }
                        def manifestDirPath = manifestOutputDirectory.asFile.get()
                        String manifestMergerpath = "$manifestDirPath/AndroidManifest.xml"


                        def link = manifestDirPath.toString()
                        link = link.replace("merged_manifests","bundle_manifest")
                        def productFlavor = link.split("/bundle_manifest/").getAt(1)
                        def upper = productFlavor.capitalize()
                        productFlavor = "process$upper" +"Manifest"
                        link = link + "/$productFlavor/bundle-manifest/AndroidManifest.xml"


                        writeManifest(manifestMergerpath,placeholders)
                        writeManifest(link,placeholders)
                }
        }
}
def writeManifest(String manifestPath,HashMap placeholders){
        def manifestContent = file(manifestPath).getText()
        placeholders.each { key, value ->
                if(key.equals("deepLinkPlaceholder")) {
                        Pattern pattern = Pattern.compile(Pattern.quote("deepLinkPlaceholder"), Pattern.DOTALL);
                        manifestContent = pattern.matcher(manifestContent).replaceAll(value);
                }
        }
        file(manifestPath).write(manifestContent)
}

FYI: There could be a better way to extract out bundle’s manifest path. I would be happy to discuss if you have any idea. 😃

仅供参考:可能会有更好的方法来提取包的清单路径。 如果您有任何想法,我很乐意讨论。 😃

6. After making all the changes inside deeplink_config.gradle file lets put it to use, Inside build.gradle call generateData() within defined productFlavors of your app in order to pass a list of domains as required by this method.If you need to insert variables into your AndroidManifest.xml file that are defined in your build.gradle file, you can do so with the manifestPlaceholders property. This property takes a map of key-value pairs.

6.在deeplink_config.gradle进行所有更改之后 该文件可以使用,在build.gradle内部调用应用程序的定义productFlavorsgenerateData() ,以传递此方法所需list of domains如果需要在定义的AndroidManifest.xml文件中插入变量在build.gradle文件中,您可以使用manifestPlaceholders属性来实现。 此属性获取键值对的映射。

productFlavors {
       appin {
           manifestPlaceholders = [hostName: "www.xyz.in", deepLinkPlaceholder: generateData("www.xyz.in", listOfDeepLinkUrls, locales, ["www.xyz.in"])]       
       }
       appza {
           manifestPlaceholders = [hostName: "www.xyz.co.za", deepLinkPlaceholder: generateData("www.xyz.co.za", listOfDeepLinkUrls, locales, ["www.xyz.co.za"])]
       }
 }

7. To test the generated <data> you can put a print(links) at the end of the generateData() additionally, you can analyze the apk or maybe open the generated manifest file as shown above.

7.要测试生成的<data> ,可以另外在generateData()的末尾放置一个print(links) ,可以分析apk打开生成的清单文件,如上所示。

Image for post
Image for post

结论 (Conclusion)

I hope this post will help you in registering your deeplinks dynamically and will make your life a lot easier in the process. Reach out to me if you think somethings can be handled even better.

希望这篇文章能帮助您动态注册深层链接,并使您的生活变得更加轻松。 如果您认为某些事情可以做得更好,请与我联系。

“The way we know things is not the way we report we know things.”

“我们了解事物的方式不是我们报告我们了解事物的方式。”

if you want to contribute to this project you can fork it to your repo.

如果您想为这个项目做贡献,可以将其添加到您的仓库中。

翻译自: https://medium.com/swlh/generating-deeplinks-dynamically-in-android-ebe503e7241f

deeplink

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值