2015-07-12 19 views
1

我想解壓android手機中的.zip文件。下面的代碼工作正常。手機在android中解壓縮文件時被吊死

public static void unzip(File zipFile, File targetDirectory) throws IOException { 
    ZipInputStream zis = new ZipInputStream(
      new BufferedInputStream(new FileInputStream(zipFile))); 
    try { 
     ZipEntry ze; 
     int count; 
     byte[] buffer = new byte[8192]; 
     while ((ze = zis.getNextEntry()) != null) { 
      File file = new File(targetDirectory, ze.getName()); 
      File dir = ze.isDirectory() ? file : file.getParentFile(); 
      if (!dir.isDirectory() && !dir.mkdirs()) 
       throw new FileNotFoundException("Failed to ensure directory: " + 
         dir.getAbsolutePath()); 
      if (ze.isDirectory()) 
       continue; 
      FileOutputStream fout = new FileOutputStream(file); 
      try { 
       while ((count = zis.read(buffer)) != -1) 
        fout.write(buffer, 0, count); 
      } finally { 
       fout.close(); 
      } 

      /* if time should be restored as well 
      long time = ze.getTime(); 
      if (time > 0) 
       file.setLastModified(time); 
      */ 
     } 
    } finally { 
     zis.close(); 
    } 

} 

當我把這種方法與參數它成功地解壓縮文件,但問題是,文件大小爲55MB,並調用此方法的應用程序之前,工作良好,但是當我調用這個方法,幾個約8秒13秒,應用程序需要解壓縮文件的應用程序卡住,沒有任何工作,但成功解壓文件後,該應用程序再次運行良好,所以請幫助我,以便應用程序應該在解壓縮文件時工作。 我也試過執行

的方法
runOnUiThread(new Runnable() { 

});

但沒有得到成功。

+0

你的代碼在[該諮詢]由CERT引用的解壓縮問題(遭受https://www.securecoding.cert.org/confluence/display/java/IDS04-J.+Safely+extract+files+from+ZipInputStream)。除了使用後面的第一個回答中看到的後臺線程外,還應考慮驗證以確保您不會解壓縮targetDirectory外的文件,並且更容易受到zip炸彈和類似攻擊的影響。我的CWAC安全庫有一個'ZipUtils'類和一個解決這些攻擊的'unzip()'方法:https://github.com/commonsguy/cwac-security/#usage-ziputils – CommonsWare

回答

2

如果應用程序凍結,通常是因爲您在主/ UI線程上執行了太多計算(請注意,runOnUiThread()完全是這樣)。爲了避免你必須在另一個線程或AsyncTask中調用你的方法。

一個快速和骯髒的解決將是使用普通螺紋:

new Thread(new Runnable() { 
    public void run() { 
     unzip(zipFile, targetDirectory); 
    } 
}).start(); 

或使用的AsyncTask:

new AsyncTask<File, Void, Void>() { 
    protected Void doInBackground(File... files) { 
     unzip(files[0], files[1]); 
     return null; 
    } 

    protected void onPostExecute(Void result) { 
     // we're finished 
    } 
}.execute(zipFile, targetDirectory); 
+0

非常感謝您的幫助。 我已經使用「AsyncTask」和它的工作很好,但一個新問題來面對如果我運行應用程序不使用「AsyncTask」,在應用程序退出「System.Exit(0)」我的應用程序成功關閉,但當我使用「 AsyncTask「,在使用」System.Exit(0)「退出應用程序之後,應用程序再次重新啓動,並使用與」AsyncTask「的」doInBackground「中所寫的方法相同的方法。所以請幫助我,我可以如何解決這個問題,以便完全關閉應用程序。 –