只添加某些外部库包

时间:2017-08-07 12:27:57

标签: java android

由于我在当前项目中需要bi-directional地图,我正在查看

  • google guava的BiMap和
  • 来自Apache Collection的BidiMap。

两个库都非常big

那么,有没有办法只从BiMap class添加guava library或从org.apache.commons.collections4.bidimap添加Apache Collection包?

欢呼声

2 个答案:

答案 0 :(得分:0)

你可以使用Pro Guard。

  

要使您的APK文件尽可能小,您应该启用收缩以删除发布版本中未使用的代码和资源。此页面描述了如何执行此操作以及如何指定在构建期间保留或丢弃的代码和资源。

请参阅: Android ProGuard Docs

另见: Stackowerflow Proguard Question

答案 1 :(得分:0)

根据建议,使用proguard还应从包含的库中删除未使用的方法和字段:https://developer.android.com/studio/build/shrink-code.html

  

ProGuard可以进行代码收缩,可以检测并删除   打包时未使用的类,字段,方法和属性   app,包括来自附带代码库的那些(使其成为   用于解决64k参考限值的有价值的工具。)

(强调我的)

如果你想手动完成,那么下面是我试图剥离guava只留下HashBiMap所需的依赖项。看起来它依赖于很多类。还要记住,proguard在字节级工作,因此剥离类永远不会像使用proguard删除未使用的代码一样有效。

我使用java 9 JDK中的jdeps来查找实现HashBiMap接口的BiMap使用的所有依赖项。这表明它递归依赖于整个番石榴罐的35%(实际上jar中存在的186个类中的666个类) - 更不用说java.base类了。重新打包的jar文件有903KB,而原始jar是2.5MB(guava-23.0-rc1-android.jar)。

下面是我使用的脚本(我还在示例android app中测试了结果jar):

# 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 *

和示例测试代码:

BiMap<String, String> myBimap = HashBiMap.create();
myBimap.put("Key", "value");
myBimap.get("key");
myBimap.inverse().get("value");