2020-12-06

Jetpack DeepLink

1.DeepLink 详解




前言

主要说明Navigation DeepLink的源代码,看如下过程的现实
1:DeepLink 三个参数详解 ,
2:DeepLink 参数解析过程 ,
3:Navgation导航目标生成过程 ,
4:Navgation如何现实导航到指定目标的,


Navigation 参数

    <declare-styleable name="NavDeepLink">
        <attr format="string" name="uri"/>
        <attr format="string" name="action"/>
        <attr format="string" name="mimeType"/>
        <attr name="android:autoVerify"/>
    </declare-styleable>

URI 参数说明

URI参考资料

https://tools.ietf.org/html/rfc3986
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web

URI格式介绍

1. Scheme://Authority:Port/Path?Query#Fragment

完整URI链接:

2.http://www.example.com:80/path/to/myfile.html?
key1=value1&key2=value2#SomewhereInTheDocument

对应关系:

Scheme ->http
Authority->www.example.com
80->port
Path->/path/to/myfile.html
Query->key1=value1&key2=value2
Fragment->SomewhereInTheDocument

URI标准scheme说明描述

SchemeDescription
dataData URIs
fileHost-specific file names
ftpFile Transfer Protocol
http/httpsHyper text transfer protocol (Secure)
javascriptURL-embedded JavaScript code
mailtoElectronic mail address
sshSecure shell
teltelephone
urnUniform Resource Names
view-sourceSource code of the resource
ws/wssWebSocket connections (Secure)

mimeType 类型说明

mime全称

 Mine:什么是 Multipurpose Internet Mail Extensions 

参考资料

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types

例子

类型描述典型示例
text表明文件是普通文本,理论上是人类可读 text/plain, text/html, text/css, text/javascript
image表明是某种图像。不包括视频,但是动态图(比如动态gif)也使用image类型image/gif, image/png, image/jpeg, image/bmp, image/webp, image/x-icon, image/vnd.microsoft.icon
audio表明是某种音频文件audio/midi, audio/mpeg, audio/webm, audio/ogg, audio/wav
video表明是某种视频文件video/webm, video/ogg
application表明是某种二进制数据application/octet-stream, application/pkcs12, application/vnd.mspowerpoint, application/xhtml+xml, application/xml, application/pdf

Action参数

Google官方描述:

操作的名称。某些标准操作在 Intent 类中定义为 ACTION_string 常量。要将其中一项操作分配给此属性,请在 ACTION_ 后跟的 string 前面加上“android.intent.action.”。例如,对于 ACTION_MAIN,请使用“android.intent.action.MAIN”;对于 ACTION_WEB_SEARCH,请使用“android.intent.action.WEB_SEARCH”。
对于您定义的操作,最好将应用的软件包名称用作前缀,以确保唯一性
例如:
可按如下方式指定 TRANSMOGRIFY 操作:
<action android:name="com.example.project.TRANSMOGRIFY" />

navigation action参数应该怎么写

  <fragment android:id="@+id/loan_main"
        android:name="com.hc.load.LoanMainFragment"
        tools:layout="@layout/fragment_loan_input_money_layout" >
        <deepLink
            android:id="@+id/deepLink"
            app:action="${applicationId}.LoanMainFragment"
          	/>
  </fragment>

为什么这样写,最后解析的结果是什么

  • 1.下面这段代码中是在NavInflater解析src/main/res/navigation/xxx.xml一段代码。
  • 2.这段代码主要解析的就是我们要将的DeepLink参数部分。
  • APPLICATION_ID_PLACEHOLDER的值就是"${applicationId}" ,如果我们的参数中包含
    这个"${applicationId}"那么会被直接替换成包名。’
  • 前面讲过为什么使用包名,主要是保证唯一性
 private void inflateDeepLink(@NonNull Resources res, @NonNull NavDestination dest, @NonNull AttributeSet attrs) throws XmlPullParserException {
        final TypedArray a = res.obtainAttributes(attrs, R.styleable.NavDeepLink);
        String uri = a.getString(R.styleable.NavDeepLink_uri);
        String action = a.getString(R.styleable.NavDeepLink_action);
        String mimeType = a.getString(R.styleable.NavDeepLink_mimeType);
        if (TextUtils.isEmpty(uri) && TextUtils.isEmpty(action) && TextUtils.isEmpty(mimeType)) {
            throw new XmlPullParserException("Every <" + TAG_DEEP_LINK
                    + "> must include at least one of app:uri, app:action, or app:mimeType");
        }
        NavDeepLink.Builder builder = new NavDeepLink.Builder();
        if (uri != null) {
            builder.setUriPattern(uri.replace(APPLICATION_ID_PLACEHOLDER,
                    mContext.getPackageName()));
        }
        if (!TextUtils.isEmpty(action)) {
            builder.setAction(action.replace(APPLICATION_ID_PLACEHOLDER,
                    mContext.getPackageName()));
        }
        if (mimeType != null) {
            builder.setMimeType(mimeType.replace(APPLICATION_ID_PLACEHOLDER,
                    mContext.getPackageName()));
        }
        dest.addDeepLink(builder.build());
        a.recycle();
    }

NavDeepLink 类源代码解析

正则表达表达式。

  • 测试正则表达式工具网址链接地址。

    https://tool.oschina.net/regex/

  • 该类中正则相关的源代码

 private static final Pattern SCHEME_PATTERN = Pattern.compile("^[a-zA-Z]+[+\\w\\-.]*:");
 "^"
 "http[s]?://"
 Pattern fillInPattern = Pattern.compile("\\{(.+?)\\}");
 Matcher matcher = Pattern.compile("(\\?)").matcher(uri);
 argRegex.append("(.+?)?");
 param.setParamRegex(argRegex.toString().replace(".*", "\\E.*\\Q"));
 Pattern mimeTypePattern = Pattern.compile("^[\\s\\S]+/[\\s\\S]+$");
 String mimeTypeRegex = "^(" + splitMimeType.mType + "|[*]+)/(" + splitMimeType.mSubType + "|[*]+)$"
 // if the deep link type or subtype is wildcard, allow anything
 String finalRegex = mimeTypeRegex.replace("*|[*]", "[\\s\\S]");
 boolean exactDeepLink = !uri.contains(".*");
 uriRegex.append("(.+?)");
 uriRegex.append("($|(\\?(.)*))");
  • 上面这些都需要一些正则相关的知识背景。 那么我们先看看和这些相关的正则基础,我们这里来个表格

    参考资料说明
    https://tool.oschina.net/uploads/apidocs/jquery/regexp.html
    https://www.runoob.com/java/java-regular-expressions.html
    在其他语言中,\ 表示:我想要在正则表达式中插入一个普通的(字面上的)反斜杠,
    请不要给它任何特殊的意义。在 Java 中,
    \ 表示:我要插入一个正则表达式的反斜线,所以其后的字符具有特殊的意义。
    Pattern fillInPattern = Pattern.compile("\{(.+?)\}");

字符含义
^匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。
$匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。
*匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等价于{0,}。
+匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
?匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”。?等价于{0,1}。
{n}n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
{n,}n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。
{n,m}m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。
?当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。
.匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“(.|\n)”的模式。
[xyz]字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。
[^xyz]负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“p”。
[a-z]字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。
[^a-z]负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。
\将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“n”匹配字符“n”。“\n”匹配一个换行符。串行“\\”匹配“\”而“\(”则匹配“(”。
\s匹配任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v] 等效。
\S匹配任何非空白字符。与 [^ \f\n\r\t\v] 等效。

明天看看NavDeepLink内部代码。太晚了,今天就到这里。睡觉去。

下面给一个完整的DeepLink给如何配置的例子

1.例子
2.源代码解读。
3.常用方式。
1.参数传递

总结

今天先到这里,明天继续

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值