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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With