0

Since i need a bi-directional map in my current project i was looking at

  • google guava's BiMap and
  • the BidiMap from Apache Collection.

Both of the libraries are pretty big

So, is there any way to just add the BiMap class from the guava library or only the org.apache.commons.collections4.bidimap package from the Apache Collection?

cheers

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
p_d
  • 101
  • 1
  • 12
  • Extract the relevant classes and add them to your own project. Or, use them as inspiration for implementing your own class. – CommonsWare Aug 07 '17 at 12:40
  • How would i go about extracting the classes i need? – p_d Aug 07 '17 at 12:49
  • https://docs.oracle.com/javase/tutorial/deployment/jar/unpack.html – OneCricketeer Aug 07 '17 at 12:50
  • You could use Gradle to exclude certain packages as well, I believe – OneCricketeer Aug 07 '17 at 12:51
  • 2
    @cricket_007: The issue here isn't packages, but individual classes within a package. Guava is a huge, everything-but-the-kitchen-sink library. I haven't looked to see the size of Apache Collection. The OP could still use the library and rely on ProGuard to get rid of excess stuff. – CommonsWare Aug 07 '17 at 12:57
  • "How would i go about extracting the classes i need?" -- both libraries are open source. So, copy the specific class that you need and add it to your project. See what it references that is missing. Copy those classes and add them to your project. Repeat until everything builds. – CommonsWare Aug 07 '17 at 12:58
  • Thanks, had a look into proguard. Probably just gonna add guava and try to make it work together with proguard. Is it a good idea to always use proguard in the final build, from my understanding it shrinks size and obfuscates the apk? – p_d Aug 07 '17 at 13:09

2 Answers2

0

You could use Pro Guard.

To make your APK file as small as possible, you should enable shrinking to remove unused code and resources in your release build. This page describes how to do that and how to specify what code and resources to keep or discard during the build.

See: Android ProGuard Docs


See also: Stackowerflow Proguard Question

Chase
  • 106
  • 1
  • 9
0

As suggested, using proguard should remove unused methods and fields also from included libraries : https://developer.android.com/studio/build/shrink-code.html

Code shrinking is available with ProGuard, which detects and removes unused classes, fields, methods, and attributes from your packaged app, including those from included code libraries (making it a valuable tool for working around the 64k reference limit).

(emphasis mine)

If you would like to do it manually then below is my try at stripping guava to leave only dependencies needed by HashBiMap. It looks like it relies on lots of classes. Also remember that proguard works at the byte level so stripping classes will never work as efficiently as removing unused code with proguard.

I used jdeps from java 9 JDK to find all the dependencies used by HashBiMap which implements BiMap interface. This show that it recursively depends on 35% of whole guava jar (actually 666 classes out of 1852 present in the jar) - not to mention java.base classes. The repackaged jar file has 903KB, while original jar is 2.5MB (guava-23.0-rc1-android.jar).

Below is script I used (I also tested resulting jar in example android app):

# cleanup
rm -rf guava_jar
rm -rf guava_jar_stripped

# unzip jar file
unzip -qq guava-23.0-rc1-android.jar -d guava_jar

# first lets see how many classes are in guava
find guava_jar -type  f | wc -l

# now use jdeps to find recursively dependencies for HashBiMap class. Each
# dependency is a class name which after some string manipulations is used
# to copy to guava_jar_stripped folder
jdeps -R -verbose -cp ./guava-23.0-rc1-android.jar ./guava_jar/com/google/common/collect/HashBiMap.class \
    | sed -En 's/(.*)->.*/\1/p' \
    | sed -e 's/[[:space:]]*$//' \
    | sed -En 's/\./\//pg' \
    | uniq \
    | xargs -n 1 -I file rsync -qavR ./guava_jar/file".class" ./guava_jar_stripped

# now lets see how many classes were copied
find guava_jar_stripped -type  f | wc -l

# now copy back manifest files
rsync -qavR ./guava_jar/META-INF/* ./guava_jar_stripped

# and finally create new jar from stripped classes
cd ./guava_jar_stripped/guava_jar
jar cf ../guava_jar.jar *

and sample test code:

BiMap<String, String> myBimap = HashBiMap.create();
myBimap.put("Key", "value");
myBimap.get("key");
myBimap.inverse().get("value");
marcinj
  • 48,511
  • 9
  • 79
  • 100