gpt4 book ai didi

android - 如何从 .apk 文件中打包的 jar 文件加载类?

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:06:20 24 4
gpt4 key购买 nike

我正在尝试从我的 .apk 文件的/assets 目录中的 jar 文件加载接口(interface)的插件实现。我能够让它工作的唯一方法是将 jar 文件提取到私有(private)外部存储,然后将该文件传递给 DexClassLoader。

这行得通,但为什么 jar 必须存在于两个地方(.apk 和私有(private)外部存储)? DexClassLoader 必须有一个文件路径作为它的参数。

有没有办法为它提供一个指向/assets 文件夹中文件的直接路径,这样我就不必用完外部存储空间来复制已经存在的内容?

以下是相关的代码 fragment :

// somewhere in my main Activity ...
final File aExtractedDexFile = new File(getDir("dex", Context.MODE_PRIVATE),
LIBRARY_DEX_JAR);
extractDexTo(aExtractedDexFile);
loadLibraryProvider(aExtractedDexFile);

/** Extract the jar file that contains the implementation class.dex and place in private storage */
private void extractDexTo(File tJarInternalStoragePath) {
BufferedInputStream aJarInputStream = null;
OutputStream aDexOutputStream = null;

try {
aJarInputStream = new BufferedInputStream(getAssets().open(LIBRARY_DEX_JAR));
aJarOutputStream = new BufferedOutputStream(new FileOutputStream(tJarInternalStoragePath));
byte[] buf = new byte[BUF_SIZE];
int len;
while ((len = aJarInputStream.read(buf, 0, BUF_SIZE)) > 0)
{
aJarOutputStream.write(buf, 0, len);
}
aJarOutputStream.close();
aJarInputStream.close();
} catch (IOException e) {
if (aDexOutputStream != null) {
try {
aJarOutputStream.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}

if (aJarInputStream != null) {
try {
aJarInputStream.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
}

/** Use DexClassLoader to load the classes from LibraryProvider */
private void loadLibraryProvider(File tFile) {
// Internal storage where the DexClassLoader writes the optimized dex file to.
final File aOptimizedDexOutputPath = getDir("outdex", Context.MODE_PRIVATE);

// Initialize the class loader with the secondary dex file.
DexClassLoader cl = new DexClassLoader(tFile.getAbsolutePath(),
aOptimizedDexOutputPath.getAbsolutePath(),
null,
getClassLoader());
Class<?> aLibProviderClazz = null;

try {
// Load the library class from the class loader.
aLibProviderClazz = cl.loadClass(LIBRARY_PROVIDER_CLASS);
sLibraryProvider = (LibraryInterface) aLibProviderClazz.newInstance();
} catch (Exception exception) {
// Handle exception gracefully here.
exception.printStackTrace();
}
}

最佳答案

有没有办法为它提供指向/assets 文件夹中文件的直接路径,这样我就不必用完外部存储空间来复制已经存在的内容?

答案是否定的。我想你会关注this blog posted by official source实现您的代码。如果有更好的做事方式,博主应该在他的博客中推荐。

解释了您需要optimizedDirectory 的原因in the API :

This class loader requires an application-private, writable directory to cache optimized classes.

还要注意assets目录在apk中是不可写的,所以不能用单纯的assets目录来完成。

博客中提到的需要复制 jar 文件的原因有点微妙:

First, it has to be copied to a storage location whose path can be supplied to the class loader.

嵌入在 apk 存档中的所有内容(文件夹/文件)在运行时都不能暴露(或解释)到底层文件系统。换句话说,DexClassLoader 和 PathClassLoader 的构造函数中都需要的 dexPath 需要一个像 /data/data/com.example/dex/common-lib.jar 这样的实体路径字符串来表示文件系统中的文件。

关于android - 如何从 .apk 文件中打包的 jar 文件加载类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10439613/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com