在apk中保留'META-INF/services'文件

Ale*_*exS 5 android meta-inf serviceloader

我有一个已经在JavaSE上工作的自定义字符集.

我的CharsetProvider的类在一个文件java.nio.charset.spi.CharsetProvider中指定,该文件位于META-INF/services并且所有内容都正常加载并按预期工作.

但是现在我也在android上使用lib,但是在Android-App中没有加载charset.

如何集成我的charset,以便在Android-App中使用它?

Charset.forName("MyCS");
Run Code Online (Sandbox Code Playgroud)

目前我正在做一个像这样的解决方法:

public static String decode(String encoding, byte[] buffer, int offset, int length) {
    String result = "";
    try {
        result = new String(buffer, offset, length, encoding);
    } catch (UnsupportedEncodingException ex) {
        MyCharsetProvider provider = new MyCharsetProvider();
        Charset cs = provider.charsetForName(encoding);
        if (cs == null) {
            Logger.getLogger(Converters.class.getName()).log(
                    Level.SEVERE,null,ex);
            result = new String(buffer, offset, length);
        } else {
            result = cs.decode(ByteBuffer.wrap(buffer, offset, length)).toString();
        }
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

哪个有效,但对我来说似乎无效,因为每次我尝试使用自己的字符集进行解码时,都会抛出异常并创建一个CharsetProvider-Object.

单一模式可以减少课程的创建.但问题是避免完全直接使用MyCharsetProvider.

编辑:

由于META-INF/services/java.nio.charset.spi.CharsetProvider在apk中缺少我虽然也许proguard删除它.然后我在proguard.cfg中尝试了以下选项:

-adaptresourcefilenames **.CharsetProvider
-adaptresourcefilecontents **.CharsetProvider
Run Code Online (Sandbox Code Playgroud)

但问题仍然存在.那么如何META-INF/services使用ant(netbeans)自动将这些文件从我的apk中获取?

Ale*_*exS 3

蚂蚁

我现在使用以下解决方案:

我创建了一个 custom_rules.xml ,其中包含以下目标,以将 META-INF/services 中的文件复制到未对齐和未签名的 apk 中。

<target name="-post-package" depends="-custom-copy" />

<target name="-copy-custom">
    <zip destfile="${out.packaged.file}"
         update="true"
         basedir="${source.absolute.dir}"
         includes="${custom.copy}" />
</target>
Run Code Online (Sandbox Code Playgroud)

在 ant.properties 中我添加了这一行

custom.copy=META-INF/services/**
Run Code Online (Sandbox Code Playgroud)

现在我只需将相关文件从库复制到我自己项目的 META-INF/services-文件夹中,即可将它们包含在 apk 中。这使我可以完全控制 ServiceLoader 加载哪些类。

备注: 目前我仅以这种方式加载外部 Java-SE-jar 中包含的实现。如果实现位于 android 项目中,则可能需要配置混淆。


ECLIPSE插件

使用 eclipse-plugin,没有像 ANT 那样的解决方法。问题是ExportHelper(第 405 行)它只是忽略META-INF文件夹中的所有内容。


Android-Studio/GRADLE

根据这个Bug,你可以META-INF在你的主项目中定义一个-directory,它将被打包到你的apk中。META-INF- 库的文件夹被排除在外,因此您被迫指定要在自己的项目中使用的实现(我认为这就是它的意图)。