2017-03-24 1 views
0

Ich habe die Funktion zum Entpacken meiner App hinzugefügt und festgestellt, dass sie sich sehr langsam entpackt. Ist es möglich, mit mehreren Threads zu entpacken? PHONE ist Samsung S6 EDGE, das ist, warum ich denke, es könnte schneller seinMulti-Thread-Entpacken. Ist es bei Android möglich?

Retrofit2 mit @Streaming, OkHttp und UNZIP:

public interface FileService { 

    @Streaming 
    @GET 
    Call<ResponseBody> downloadFile(@Url String fileUrl); 
} 

mFileService.downloadFile(mScheme.getmPath()).enqueue(new Callback<ResponseBody>() { 
     @Override 
     public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { 
      new AsyncTask<ResponseBody, Long, Boolean>() { 
       @Override 
       protected Boolean doInBackground(final ResponseBody... responseBodies) { 

        ResponseBody body = responseBodies[0]; 
        long length = body.contentLength(); 
        unzip(body); 
        return true; 
       } 

       @Override 
       protected void onProgressUpdate(Long... values) { 
        super.onProgressUpdate(values); 
        pb.setProgress(values[0].intValue()); 
        tv.setText(values[0].intValue()+"%"); 
       } 

       @Override 
       protected void onPostExecute(Boolean aBoolean) { 
        super.onPostExecute(aBoolean); 
        if(aBoolean){ 

         realm.executeTransaction(new Realm.Transaction() { 
          @Override 
          public void execute(Realm realm) { 
           m.setDownloaded(true); 
           mScheme.setDownloaded(true); 
           mScheme.setmPath(mScheme.getmPath().substring(0,mScheme.getmPath().indexOf(".zip"))); 
           //realm.insertOrUpdate(m); 
           //realm.insertOrUpdate(mScheme); 
          } 
         }); 
         Log.d(TAG, mScheme.getmPath()); 
        } 
       } 

       private void unzip(ResponseBody body) { 

        long fileSize = body.contentLength(); 
        long fileSizeDownloaded = -1; 

        try { 
         InputStream in = body.byteStream(); 
         ZipInputStream zin = new ZipInputStream(in); 
         ZipEntry ze = null; 
         while ((ze = zin.getNextEntry()) != null) { 
          Log.v("Decompress", "Unzipping " + ze.getName()); 

          if(ze.isDirectory()) { 
           _dirChecker(ze.getName()); 
          } else { 
           FileOutputStream fout = new FileOutputStream(Constants.CONFIG.CACHE_LOCATION + ze.getName()); 
           for (int c = zin.read(); c != -1; c = zin.read()) { 
            publishProgress(fileSizeDownloaded * 100/fileSize); 
            fileSizeDownloaded++; 
            fout.write(c); 
           } 

           zin.closeEntry(); 
           fout.close(); 
          } 

         } 
         zin.close(); 
         Log.d("Decompress", "done"); 
        } catch(Exception e) { 
         Log.e("Decompress", "unzip", e); 
        } 

       } 

       private void _dirChecker(String dir) { 
        File f = new File(Constants.CONFIG.CACHE_LOCATION + dir); 

        if(!f.isDirectory()) { 
         f.mkdirs(); 
        } 
       } 
      }.execute(response.body()); 

     } 

     @Override 
     public void onFailure(Call<ResponseBody> call, Throwable t) { 
      t.printStackTrace(); 
     } 

    }); 

Antwort

1

Dieser Code:

for (int c = zin.read(); c != -1; c = zin.read()) { 
    publishProgress(fileSizeDownloaded * 100/fileSize); 
    fileSizeDownloaded++; 
    fout.write(c); 
} 

Ein Byte zu lesen ist ziemlich langsam. Dies könnte beschleunigen:

byte[] buffer = new byte[4096]; 
int bytesRead; 
while ((bytesRead = zin.read(buffer)) != -1) { 
    publishProgress(fileSizeDownloaded * 100/fileSize); 
    fileSizeDownloaded += bytesRead; 
    fout.write(buffer, 0, bytesRead); 
} 

Vielleicht können Sie Verarbeitung parallelisieren durch einen separaten Thread für jede Datei, die Dispatching unzipping muss.

+0

Sie sind HERO meines Tages)) –

+0

@ ЧечилКрым Wenn es Ihnen geholfen hat, bitte in Betracht ziehen, die Antwort – nandsito

+0

über "parallelize Verarbeitung" zu akzeptieren. Können Sie mir bitte einige Artikel zeigen? –

Verwandte Themen