URI is not hierarchical

1,735 阅读1分钟

[TOC]

URI is not hierarchical

// File.java
public File(URI uri) {

        // Check our many preconditions
        if (uri.isOpaque())
            throw new IllegalArgumentException("URI is not hierarchical");
}
// URI.java
public boolean isOpaque() {
        return path == null;
}

问题出现的背景

最近在写一个关于自动生成 Xposed 测试代码以及引入 whale.so 文件的插件。在将插件中的 whale.so 文件拷贝到项目中的 libs/armeabi/ 文件夹下的时候,出现了这个异常。

我在插件中使用了如下代码将 whale.so 拷贝至目标路径。

 String abiPath ="./libs/armeabi/";
 URI uri = GeneralXposed.class.getResource("libwhale.so").toURI();
 new Thread(() -> FileUtils.copyToTargetDir(new File(uri), abiPath)).start();

该代码在IDEA中,自测时没有出现任何异常,只有在作为插件,在项目中使用时,才出现了该错误。

问题的原因

通过getResource获取的so文件,我们不能对它的数据进行操作。如果我们要对数据进行操作,就必须用 getResourceAsStream,得到一个文件的读取流,通过该文件流操作文件。

为什么 getResource 不能直接操作文件的数据那?

通过上面的错误出处,我们不难发现:由于我们通过 getResource 获取的 URI 是非透明的,所以系统抛出了该异常。那么什么情况下是非透明的那?当且仅当URI是绝对的且特定于方案的部分不是以斜线/开始时,URI才是非透明的。这么说比较抽象,来看下我碰到的: jar:file:/C:/GeneralXposed.jar!/com.ming.plugin/whale.so 这说明:我们jar中的文件对 AndroidStudio 来说是不透明的,对IDEA来说是透明的。所以,当我们在jar中访问时,才会出现该错误。

问题的解决方式

我们应该使用 getResourceAsStream 实现对插件资源的访问。