解压过程使设备无响应

问题描述:

运行下面的代码解压缩70 MB的压缩文件(其中包含750个文件)时,该设备变得无响应,几乎崩溃。谁能告诉我什么是错的:解压过程使设备无响应

boolean UNZipFiles() { 
    float prev = -1; // to check if the percent changed and its worth updating the UI 
    int finalSize = 0; 
    float current = 0; 

    try { 
     final int BUFFER = 2048; 
     String zipFilePath = PATH + FileName; 

     BufferedOutputStream dest = null; 
     BufferedInputStream is = null; 
     ZipEntry entry; 
     ZipFile zipfile = new ZipFile(zipFilePath); 

     finalSize = (int) new File(zipFilePath).length(); 

     Enumeration<? extends ZipEntry> e = zipfile.entries(); 
     while (e.hasMoreElements()) { 
      entry = e.nextElement(); 
      current += entry.getCompressedSize(); 

      if (entry.isDirectory()) 
       dirChecker(entry.getName()); 
      else { 
       int count; 
       byte data[] = new byte[BUFFER]; 

       is = new BufferedInputStream(zipfile.getInputStream(entry)); 
       FileOutputStream fos = new FileOutputStream(PATH + entry.getName()); 
       dest = new BufferedOutputStream(fos, BUFFER); 
       while ((count = is.read(data, 0, BUFFER)) != -1) 
        dest.write(data, 0, count); 

       if (prev != current/finalSize * 100) { 
        prev = current/finalSize * 100; 

        UpdatePercentNotificationBar((int) prev); 
       } 

       dest.flush(); 
       dest.close(); 
       is.close(); 
      } 
     } 


     DeleteZip(zipFilePath); 

     success = true; 
    } catch (Exception e) { 
     NotificationBarFail("Error while Downloading"); 
     return false; 
    } 

    return true; 

} 

通知管理:

public void onCreate() {   
    super.onCreate(); 
    mContext = this; 

    Intent intent = new Intent(this, Main.class); 
    pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0); 
    notification = new Notification(R.drawable.icon, "Downloading files", System.currentTimeMillis()); 
    notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT; 
    notification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.background_service); 
    notification.contentIntent = pendingIntent; 
    notification.contentView.setImageViewResource(R.id.status_icon, R.drawable.icon); 
    notification.contentView.setTextViewText(R.id.status_Percentage, "0%"); 
    notification.contentView.setProgressBar(R.id.status_progress, 100, progress, false); 

    notificationManager = (NotificationManager) getApplicationContext().getSystemService(NOTIFICATION_SERVICE); 

    notificationManager.notify(42, notification); 
    FileName = Main.Main_File_Name; 
} 

新代码:

boolean UNZipFiles() { 
     byte[] buffer = new byte[4096]; 
     int length; 
     float prev = -1; // to check if the percent changed and its worth updating the UI 
     int finalSize = 0; 
     float current = 0; 

     try { 

      String zipFile = PATH + FileName; 

      FileInputStream fin = new FileInputStream(zipFile); 
      ZipInputStream zin = new ZipInputStream(fin); 

      finalSize = (int) new File(zipFile).length(); 

      ZipEntry ze = null; 

      while ((ze = zin.getNextEntry()) != null) { 
       current += ze.getCompressedSize(); 
       if (ze.isDirectory()) 
        dirChecker(ze.getName()); 
       else { 
        FileOutputStream fout = new FileOutputStream(PATH + ze.getName()); 
        while ((length = zin.read(buffer)) > 0) 
         fout.write(buffer, 0, length); 
        if (prev != current/finalSize * 100) { 
         prev = current/finalSize * 100; 

         UpdatePercentNotificationBar((int) prev); 
        } 
        zin.closeEntry(); 
        fout.close(); 
       } 

      } 
      zin.close(); 
      DeleteZip(zipFile); 


      success = true; 
     } catch (Exception e) { 
      NotificationBarFail("Error while downloading"); 
      return false; 
     } 

     return true; 

    } 
+0

也许你正在主应用程序线程上调用此代码。 – CommonsWare 2012-08-12 13:46:16

+0

@CommonsWare此代码正在IntentService中运行。在上面的代码中似乎没有任何错误/可以改进?我更新了整个功能的代码,它包括更新通知 – Omar 2012-08-12 14:12:56

+0

进一步测试时,我得到了“系统UI停止工作”! – Omar 2012-08-12 14:32:38

在你的代码,你在呼唤UpdatePercentNotificationBar超过100个零件因为您正在使用prev的浮点值,所以每个循环都会生成一条新消息。

原文:

float prev; 
... 
if (prev != current/finalSize * 100) { 
    prev = current/finalSize * 100; 
    UpdatePercentNotificationBar((int) prev); 
} 

应该是这样的:

int prev; 
... 
if (prev != (int)(current/finalSize * 100)) { 
    prev = (int)(current/finalSize * 100); 
    UpdatePercentNotificationBar(prev); 
} 

当你改变这个逻辑,你不再充斥消息UI证实。