Допустим мы пишем библиотеку, она использует другие библиотеки и, в частности, для примера, support library. Если бы мы использовали maven, то в pom файле просто прописали зависимости и не парились. Но что если нашу библиотеку будут использовать люди, которые не пользуются системами сборок или пользуются ant’ ом?
Мы можем положить зависимости рядом с нашим jar. Но тогда неизбежны конфликты библиотек разных версий, например, если мы используем одну версию support library, а в самом приложении другая. Тогда придется руками одну из них удалять.
Можно пойти другим путем, вспомним что jar это обычный zip файл. Мы распакуем все зависимости, добавим код нашей библиотеки и скомпилируем. На выходе получим цельный jar файл со всеми зависимостями. Но если в приложении используются те же библиотеки что и у нас, то получим ошибку что в проекте два одинаковых класса.
Для решения этой проблемы воспользуемся утилитой jarjar. Она переименовывает все классы в jar файле. На примере support library — все классы находятся в пакете android.support.v4
Пример использования:
java -jar jarjar.jar process <rulesFile> <inJar> <outJar> rulesFile - файл с правилами переименования inJar, outJar - тут все понятно
Создадим правило для переименования классов android.support.v4.* в inner.android.support.v4.*
rule android.support.v4.** inner.android.support.v4.@1
и сохраним в файл rules.txt
Запускаем
java -jar jarjar.jar rules.txt android-support-v4.jar android-support-v4-renamed.jar
В итоге получили jar’ку с переименованными классами. Далее мы распаковываем все наши зависимости с переименованными классами и компилируем. Получаем библиотеку, которая содержит весь код нужный для выполнения.
Наша библиотека содержит код всех зависимостей, которые могут весить немало. Чтобы уменьшить размер применим proguard для удаления неиспользуемых классов и методов.
И в заключение небольшой скрипт на gradle который всё это делает
apply plugin: 'java' defaultTasks 'proguard' task unpackJars(dependsOn: compileJava) { //распаковываем классы из библиотек file('libs').listFiles().each { File file -> if (file.name.endsWith('.jar')) { copy { from(zipTree(file.path)) into('build/classes/main') } } } //собираем jar'ку tasks.jar.execute() } task proguard(type: proguard.gradle.ProGuardTask, dependsOn: unpackJars) { injars 'build/libs/library.jar' outjars 'build/libs/proguard_library.jar' libraryjars '/Applications/my/Android Studio.app/sdk/platforms/android-10/android.jar' //укажем что классы нашей библиотеки удалять не нужно keep 'class com.CasualSoftware.classloader.library.*' } dependencies { compile 'com.google.android:android:2.2.1' compile fileTree(dir: 'libs', include: ['*.jar']) }
Вои и всё, после выполнения скрипта мы получим proguard_library.jar, который можно добавлять к приложению и использовать.
В моём случае библиотека использует support library и dropbox sdk, и весит 522 байта.
ссылка на оригинал статьи http://habrahabr.ru/post/219801/
Добавить комментарий