Читаем XLSX на Android 5 (ART)

от автора

Некоторое время назад я писал, как при помощи языческих танцев и прочих паранормальных активностей я добился работы Apache POI XSSF на Android 4. Всё становится гораздо проще с Android Build Tools (21+) и Android 5 (ART).

Теперь достаточно собрать проект с поддержкой multi-dex и всё будет работать* на устройствах c ART. Я полагаю, что это происходит благодаря Ahead-of-time (AOT) compilation на устройстве и multi-dex теперь, как таковой, нужен только как промежуточный этап.

* К сожалению не всё так гладко. В зависимостях проекта есть xmlbeans-2.6.0.jar, который запакован с ошибкой и содержит дубликаты классов. Это приводит к провалу сборки на задаче packageAllDebugClassesForMultiDex, со следующей ошибкой:

Error:Execution failed for task ':app:packageAllDebugClassesForMultiDex'. > java.util.zip.ZipException: duplicate entry: org/apache/xmlbeans/xml/stream/Location.class 

XMLBeans придётся перепаковать.
Этот дефект уже сто лет в обед как зарегистрирован issues.apache.org/jira/browse/XMLBEANS-499, однако воз и ныне там.

Для полноценной работы нам понадобятся следующие JAR файлы:
poi-3.12-20150511.jar
poi-ooxml-3.12-20150511.jar
poi-ooxml-schemas-3.12-20150511.jar
stax-1.2.0.jar
stax-api-1.0.1.jar
xmlbeans-2.6.0.jar — из-за этого файла не получится беззаботно добавить POI в зависимости проекта

Все вышеуказанные файлы доступны в загрузках POI archive.apache.org/dist/poi/release/bin

Чтобы всё заработало нужно:

  • добавить com.android.support:multidex в зависимости проекта.
  • Включить multiDex в defaultConfig
  • для задачи com.android.build.gradle.tasks.Dex добавить параметр —core-library, чтобы избежать ошибок из за классов с namespace javax.

Если использовать gradle, то получим конфиг примерно следующего содержания:

apply plugin: 'com.android.application' android {     compileSdkVersion 22     buildToolsVersion "22.0.1"     defaultConfig {         //другие стандартные настройки         minSdkVersion 21         targetSdkVersion 21                 multiDexEnabled true     }     buildTypes {         release {             minifyEnabled false             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'         }     }     //исключим текстовые файлы:     packagingOptions {         exclude 'META-INF/DEPENDENCIES'         exclude 'META-INF/NOTICE'         exclude 'META-INF/NOTICE.txt'         exclude 'META-INF/LICENSE'         exclude 'META-INF/LICENSE.txt'     }     project.tasks.withType(com.android.build.gradle.tasks.Dex) {         additionalParameters=['--core-library'] //javax namespace fix     } } dependencies {     // ... остальные зависимости проекта ...     compile 'com.android.support:multidex:1.0.1' } 

Всё! Теперь мы имеем, предположительно, полностью функциональный POI на Android, который, опять таки, предположительно, может читать и все остальные openxml форматы, поскольку нам не пришлось обрезать содержимое jarов, как это было сделано в прошлый раз. Прошу любиить, экспериментировать и делиться результатами.
При желании можно также озадачиться тем, чтобы сделать javax->aavax хак, но в этот раз я счёл это лишним.

Если очень хочется, чтобы зависимости вытягивались сами, то можно написать рутину для multidex.JarMergingTask, которая бы перепаковывала jar xmlbeans, и я даже написал такую рутину. Однако, после этого билд стал валиться на preDex из-за javax в stax-api. Мне не удалось найти быстрого способа добавить —core-library в preDex и на этом у меня кончилось терпение. Наиболее разумным мне кажется просто добавить все необходимые jarы, вместе с перепакованным xmlbeans в libs проекта.

В качестве заключения:
Я сделал два jara содержащих всё необходимое и не содержащие дубликатов в xmlbeans, файлы можно скачать в этом репозитории:
github.com/andruhon/android5xlsx пользуйте на здовровье, но на свой страх и риск.

ссылка на оригинал статьи http://habrahabr.ru/post/267381/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *