Uri内部处理流程分析

本文详细探讨了Android中Uri的内部处理流程,从Uri的基本结构到解析过程,揭示了即使在Uri后面添加特定字符串仍能成功加载图片的原因。通过分析Uri的parse方法、getDrawableFromUri方法及其内部细节,如scheme、authority、path的获取,展示了Uri如何在内容提供器中找到对应的资源ID。
摘要由CSDN通过智能技术生成

*本篇文章已授权微信公众号guolin_blog (郭霖) 独家发布


 

前几天在讨论一个很有趣的事情:同事在交流时发现Uri在parse生成时,在里面加入一段其他无关的字符串,同样可以得到想要的值,这么说不太直观,直接上代码吧:

ImageView img = findViewById(R.id.img);

Uri uri =Uri.parse("android.resource://"+getPackageName()+R.drawable.mkf);
img.setImageURI(uri);

简单说明一下:要做的是通过一个Uri去给ImageView控件添加src图片。通过setImageURI的方法。

在过程中发现了一个很有趣的问题:上述代码如果改成这几个样子,同样可以达到效果:

Uri uri =Uri.parse("android.resource://"+getPackageName()+"/adasdasd/"+R.drawable.mkf);

Uri uri =Uri.parse("android.resource://"+getPackageName()+"/我就是瞎写的/"+R.drawable.mkf);

Uri uri =Uri.parse("android.resource://"+getPackageName()+"//"+R.drawable.mkf);

发现在getPackageName后面添加一段什么东西(但是格式必须是前面有‘/’),都会成功的把图片加载出来。当时就感觉很奇怪,于是拔了一下Uri关于其中的部分源码,最后知道了其中的所以然,伙伴们不要着急哈,让我慢慢道来:


关于Uri的介绍

可能有些朋友对Uri只是使用过,但是不知道到底是个什么东西,在这里笔者简单的说明一下。Uri全称为统一资源标识符(Uniform Resource Identifier),这里不想扯太多,简单理解的话就是对于一个资源名称的命名,如果有想详细了解的话请看这个大神的博客:Java魔法堂:URI、URL(含URL Protocol Handler)和URN

而Java中还有一个URI(全大写),他们两个都是统一资源标识符,只是Uri是在URI的基础上拓展了一些属性,用来适用于Android开发而已。

Uri结构

从结构程度上,一般可以把Uri的结构分为三种:

1.基本结构:这种结构是Uri最简单的结构,分为三个部分

[scheme:]scheme-specific-part[#fragment]

2.进一步划分:将scheme-specific-part进一步划分为了authority、path、query

[scheme:][//authority][path][?query][#fragment]

3.最终结构:将authority划分为host和post

[scheme:][//host:port][path][?query][#fragment]

举个例子来说明:

https://mp.csdn.net/postedit/81806443
scheme: https:
authority(host) //mp.csdn.net
path /postedit/81806443

简单说明一下规则:

  • 对于Uri,scheme和authority是不能省略的,其他的部分可以有也可以没有。
  • 一般authority中如果没有出现post:host格式,都是post出现
  • path和query可以连缀重复出现,其中query需要通过&俩连缀,而path只是继续添加/

好了,对Uri的介绍就到这里,下面是我们的追源码时间。


处理流程

既然Uri是我们创建的,我们就从parse方法看起:

    public static Uri parse(String uriString) {
        return new StringUri(uriString);
    }

他返回了一个StringUri对象,点进构造方法我们看一下:

    private StringUri(String uriString) {
        if (uriString == null) {
            throw new NullPointerException("uriString");
        }

        this.uriString = uriString;
    }

他只是将传入的String赋值给了这个StringUri,让他储存起来。

在这里有必要说一下StringUri是个什么东西。对于Uri来说,本身是有一定限制的,比如无法实现层次化和透明化的Uri,但是StringUri在其基础上继承了AbstractHierarchicalUri类,从而达到可以层次化、透明的效果,关于层次、透明具体可以看上面的那篇文章。

对于StringUri只需要知道他只是Uri的一个子类,上面的如果不想深入只了解一下就可以的。

看来我们parse方法没有干什么大事,就是原封不动的全扔进去了,看来我们只能从ImageView的setImageURI方法入手了:</

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值