Hacking by Walkingice: Exclude dependency jar file from apk when using Ant for Android


Exclude dependency jar file from apk when using Ant for Android

To put it simply, Android ant packages each jar files under directory libs to the destination apk file, but I don't wanna it. This is just workaround. (I am using Android SDK Tools 22.0.1)

I am writing a simple Bluetooth 4.0 application which base on Samsung series mobile phone. Android is going to support Bluetooth 4.0 but it does not happen so far. That means I still need using Samsung BLE SDK to use Bluetooth 4.0, that's ok.

When I started learning Samsung BLE SDK via attached samples, it works well. It is build-able under Eclipse, it works. When I used Ant to build the apk (yes, I used to use command-line tool to do developing.), it failed.

I got a run-time error:  <A Class> had used a different <B class>; during pre-verification

W/dalvikvm(22070): Class resolved by unexpected DEX: Lcom/samsung/ble/pxpmonitor/ProximityService$3;(0x430e85d0):0x40086000 ref [Lcom/samsung/android/sdk/bt/gatt/BluetoothGattCallback;] Lcom/samsung/android/sdk/bt/gatt/BluetoothGattCallback;(0x430e85d0):0x40038000
W/dalvikvm(22070): (Lcom/samsung/ble/pxpmonitor/ProximityService$3; had used a different Lcom/samsung/android/sdk/bt/gatt/BluetoothGattCallback; during pre-verification)
W/dalvikvm(22070): Unable to resolve superclass of Lcom/samsung/ble/pxpmonitor/ProximityService$3; (60)
W/dalvikvm(22070): Link of class 'Lcom/samsung/ble/pxpmonitor/ProximityService$3;' failed
D/AndroidRuntime(22070): Shutting down VM
W/dalvikvm(22070): threadid=1: thread exiting with uncaught exception (group=0x41f83930)
E/AndroidRuntime(22070): FATAL EXCEPTION: main
E/AndroidRuntime(22070): java.lang.NoClassDefFoundError: com/samsung/ble/pxpmonitor/ProximityService$3
E/AndroidRuntime(22070):        at com.samsung.ble.pxpmonitor.ProximityService.(ProximityService.java:195)
E/AndroidRuntime(22070):        at java.lang.Class.newInstanceImpl(Native Method)
E/AndroidRuntime(22070):        at java.lang.ClassLoader.loadClass(ClassLoader.java:461) 

Because the apk file I built contains ble_sdk.jar, and Samsung Galaxy S4 has the same (at least, the same name) implementation under /system/framework.

The problem is that I have to build some classes which depend on ble_sdk.jar, but I cannot package the ble_sdk.jar into apk file since it makes duplication.

In general, we put dependency libraries to directory libs, but the dex-helper macro in Android Ant build system merges EVERY JAR FILES INTO classes.dex. Cool, that bites me.

To put the ble_sdk.jar outside directory libs and asks ant-building-system refer to it? it doesn't work, we even cannot override the property jar.libs.dir. (issue #33194)

I tried to figure it out but quit with no luck. If you know a good way match my requirement, please tell me. This is my workaround. (workaround means --- Someday I will bite myself.)

Workaround: Do not package each jar under libs unless I ask you to do that.

Add a custom_rules.xml to your project with these statements.

<target name="-post-compile">
        <path id="project.all.jars.path">
                <!-- un-comment below line if you want it-->
                <!-- <pathelement path="libs/please_package_this.jar"> -->
        <echo level="info">To be packaged jar: ${toString:project.all.jars.path}

It cleans project.all.jars.path that defines Android ant-building-system's merge targets. I don't like this idea but it basically works.

1 comment:

  1. If you are using "android update project ..." to establish your ant build environment, you may consider to specify the command line option as

    ant -Djava.compiler.classpath=${path-of-the-jar-file} ...

    This just triggers the compile time validation without including the jar into the apk.