2012-03-24 1 views
0

У меня есть база данных 20 МБ, хранящаяся в активах apk, которые при первом запуске извлекаются для использования. Для этого я используюUnzip из активов не работает при использовании proguard

PackageManager pm = context.getPackageManager(); 
String apkFile = pm.getApplicationInfo(context.getPackageName(), 0).sourceDir; 
ZipFile zipFile = new ZipFile(apkFile); 
ZipEntry entry = zipFile.getEntry("assets/FILENAME"); 
myInput = zipFile.getInputStream(entry); 
myOutput = new FileOutputStream(file); 
    byte[] buffer = new byte[1024*4]; 
int length; 
int total = 0; 
int counter = 1; 
while ((length = myInput.read(buffer)) > 0) { 
    total += length; 
    counter++; 
    if (counter % 32 == 0) { 
     publishProgress(total); 
    } 
     myOutput.write(buffer, 0, length); 
} 

Все отлично работает, когда я экспортировать из затмения (андроид 2,2 целевых) без использования ProGuard. Когда я экспортирую с proguard, unzip начинает работать в течение нескольких секунд (и несколько обновлений прогресса, до 8%), но затем сбой java.io.IOException в java.util.zip.InflaterInputStream.read (..)

Он работает на эмуляторе, но падает на устройства (многие устройства, но я думаю, что всегда работает на Android 4, сбой в Android 2.2). Мой proguard.cfg в основном по умолчанию. Ничего, что я пробовал изменить, кажется, помогает, любые идеи?

+0

Почему вы не используете 'getResources(). GetAssets()', чтобы получить 'AssetManager', и использовать его для получения своих активов? – CommonsWare

+0

Я считаю, что он ограничен файлами размером менее 1 Мбайт, по крайней мере, на Android 2, тогда как прямая распаковка работает (по крайней мере, без proguard). – wordy

+0

'AssetManager' отлично работает для файлов с 1 + МБ. Тем не менее, они должны иметь расширение файла, которое предотвращает их сжатие. ['SQLiteAssetHelper'] (https://github.com/jgilfelt/android-sqlite-asset-helper), например, отлично работает с файлами 1 + МБ, благодаря простоте хранения их ZIP-архивов в' assets/'project. – CommonsWare

ответ

0

Оптимизация ProGuard может выявлять ошибки в обрабатываемом коде. Например, оптимизация может потенциально изменить время многопоточного кода, вызывая проблемы, если он не синхронизирован должным образом. Вы можете дважды проверить свой код. Например, поля myInput и myOutput, которые обрабатываются в других потоках? Является ли проблема детерминированной?

Оптимизация ProGuard также может выявлять ошибки на виртуальной машине или во временных классах. Возможно, вы столкнулись с ошибкой, исправленной в последних версиях Android.

Поскольку обработанный код действительно работает в последних версиях Android, это, вероятно, не ошибка в ProGuard, но вы можете проверить, имеет ли последняя версия значение (версия 4.7 на момент написания).

Вы можете сообщить о проблеме, связанной с ProGuard's bug tracker, с образцом, который иллюстрирует проблему (по крайней мере, с более полным кодом и полной трассировкой стека). В то же время вы можете обойти это, отключив оптимизацию.

+0

Насколько я могу судить, он детерминирован, а резьба тривиальна. Спасибо, действительно, это может быть ошибка в android. На данный момент я думаю, что предложение CommonsWare - лучшее решение - я приму в качестве ответа, если он захочет опубликовать ответ (хотя, конечно, не ответ на исходный вопрос). – wordy