2012-03-24 56 views
0

我有一個存儲在apk資源中的20MB數據庫,它在第一次運行時被提取使用。要做到這一點,我用我的時候不使用ProGuard從日食(Android 2.2的目標)出口使用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); 
} 

一切工作正常。當我用proguard導出時,解壓縮開始工作幾秒鐘(並且一些進度更新,到8%),但是隨後在java.util.zip.InflaterInputStream.read()中崩潰。 )

它適用於模擬器,但在設備上崩潰(很多設備,但我認爲總是在Android 4中工作,在Android 2.2中崩潰)。我的proguard.cfg基本上是默認的。 沒有我試過改變似乎有幫助,任何想法?

+0

爲什麼不使用'getResources()。getAssets()'獲取'AssetManager',並使用它來獲取您的資產? – CommonsWare 2012-03-24 13:05:27

+0

我相信只限於文件少於1MB,至少在Android 2上,而直接解壓縮的作品(至少沒有proguard)。 – wordy 2012-03-24 19:29:49

+0

'AssetManager'適用於1 MB文件。但是,他們必須有一個文件擴展名,以防止它們被壓縮。例如,對於1 MB文件,['SQLiteAssetHelper'](https://github.com/jgilfelt/android-sqlite-asset-helper)可以很好地工作,通過簡單的方法將它們存儲在'資產/'項目文件夾。 – CommonsWare 2012-03-24 19:39:00

回答

0

ProGuard優化可能會在處理的代碼中發現錯誤。例如,優化可能會改變多線程代碼的時序,如果它沒有正確同步就會造成問題。你可以仔細檢查你的代碼。例如,myInput和myOutput字段是否在其他線程中操作?問題是確定性的嗎?

ProGuard優化還可能發現虛擬機或運行時類中的錯誤。您可能遇到了最近版本的Android中已修復的錯誤。

由於處理後的代碼在最新版本的Android上工作,它可能不是ProGuard中的錯誤,但您可以檢查最新版本是否有所作爲(本文撰寫時爲4.7版)。

您可以在ProGuard的bug tracker上報告問題,並舉例說明問題(至少使用更完整的代碼和完整的堆棧跟蹤)。與此同時,您可以通過關閉優化來解決此問題。

+0

據我所知,它是確定性的,線程是微不足道的。 謝謝,的確,它可能是Android中的一個錯誤。目前我認爲CommonsWare的建議是最好的解決方案 - 如果他想作爲答案張貼(儘管當然不是對原始問題的答案),我會接受作爲答案。 – wordy 2012-03-25 09:27:48