I have a custom charset which is already working on JavaSE.
The class of my CharsetProvider is specified in a file java.nio.charset.spi.CharsetProvider
which is located in META-INF/services
and everything get's loaded normally and works as expected.
However now I'm using the lib on android as well, but the charset isn't loaded in Android-App.
How can I integrate my charset, so that it can be used like expected in an Android-App?
Charset.forName("MyCS");
At the moment I'm doing a workaround like this:
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;
}
Which works, but seems ineffective to me, since everytime I try to decode like this with my own charset, an exception will be thrown and a CharsetProvider-Object will be created.
The creation of course could be reduced by singleton pattern. But the issue is to avoid the direct usage of MyCharsetProvider entirely.
EDIT :
Since META-INF/services/java.nio.charset.spi.CharsetProvider
is missing in the apk I though maybe proguard removes it. I then tried the following options in proguard.cfg:
-adaptresourcefilenames **.CharsetProvider
-adaptresourcefilecontents **.CharsetProvider
But the problem still persists. so how can I get these files from META-INF/services
into my apk automatically using ant (netbeans)?
ANT
I'm using the following solution now:
I created a custom_rules.xml with the followin targets to copy files in META-INF/services into the unaligned and unsigned 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>
And in ant.properties I added the line
custom.copy=META-INF/services/**
Now I just have to copy relevant files from libraries to the META-INF/services-folder of my own project to include them in the apk. This gives me full control over which classes to be loaded by ServiceLoader.
Remark: Currently I only load implementations that are included in external Java-SE-jars this way. Obfuscation may have to be configured if the implementations are in an android-project.
ECLIPSE-PLUGIN
Using the eclipse-plugin, there's no workaround like in ANT. The problem is the ExportHelper (line 405) which just igores everything in META-INF
folders.
Android-Studio/GRADLE
According to this Bug you may define a META-INF
-directory in your main project and this will be packaged into your apk. META-INF
-folders of libraries are excluded, so that you are forced to specify the implementations you want to use in your own project (I think this is the intention of it).