[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 实现对插件资源的访问。