Progress Bar with unzipping of file

2019-03-22 04:33发布

问题:

I am trying to update a progress bar with unzipping of file in the sd card. My unzipping works fine but the progress bar does not appear. Here is my code in mainactivity:

private ProgressBar bar;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    bar = (ProgressBar) findViewById(R.id.progress);

    String zipFilename = Environment.getExternalStorageDirectory() + "path to my zip file in sd card";  
    String unzipLocation = Environment.getExternalStorageDirectory() + "the output folder";  




    Decompress d = new Decompress(zipFilename, unzipLocation);  
    d.unzip(); 
}

public class Decompress {   
    private String _zipFile;   
    private String _location;
    private int per = 0;



    public Decompress(String zipFile, String location) {
        _zipFile = zipFile;     
        _location = location;      
        _dirChecker("");   
        }    
    public void unzip() {     
        try  {       
            ZipFile zip = new ZipFile(_zipFile);
            bar.setMax(zip.size());
            FileInputStream fin = new FileInputStream(_zipFile);       
            ZipInputStream zin = new ZipInputStream(fin);
            ZipEntry ze = null;       
            while ((ze = zin.getNextEntry()) != null) {

                Log.v("Decompress", "Unzipping " + ze.getName());          
                if(ze.isDirectory()) {           
                    _dirChecker(ze.getName());         
                    } else {      
// Here I am doing the update of my progress bar

                        per++;
                        bar.setProgress(per);
                        FileOutputStream fout = new FileOutputStream(_location + ze.getName());           
                        for (int c = zin.read(); c != -1; c = zin.read()) {  

                            fout.write(c);           
                            }            
                        zin.closeEntry();          
                        fout.close();         
                        }                
                }       
            zin.close();    
            } catch(Exception e) {       
                Log.e("Decompress", "unzip", e);    
                }    
        }    
    private void _dirChecker(String dir) {     
        File f = new File(_location + dir);      
        if(!f.isDirectory()) {       
            f.mkdirs();     
            }   
        }

    }
}

回答1:

Your unzipping code is running on the Main/UI thread, thereby freezing the UI. You want to do the unzipping in a background thread using AsyncTask.

Example for your case:

 private class Decompress extends AsyncTask<Void, Integer, Integer> {

   private String _zipFile;   
   private String _location;
   private int per = 0;

   public Decompress(String zipFile, String location) {
       _zipFile = zipFile;     
       _location = location;      
       _dirChecker("");   
   }


    @Override
    protected Integer doInBackground() {
        try {
            ZipFile zip = new ZipFile(_zipFile);
            bar.setMax(zip.size());
            FileInputStream fin = new FileInputStream(_zipFile);
            ZipInputStream zin = new ZipInputStream(fin);
            ZipEntry ze = null;
            while ((ze = zin.getNextEntry()) != null) {

                Log.v("Decompress", "Unzipping " + ze.getName());
                if (ze.isDirectory()) {
                    _dirChecker(ze.getName());
                } else {
                    // Here I am doing the update of my progress bar

                    per++;
                    publishProgress(per);

                    FileOutputStream fout = new FileOutputStream(_location + ze.getName());
                    for (int c = zin.read(); c != -1; c = zin.read()) {
                        fout.write(c);
                    }
                    zin.closeEntry();
                    fout.close();
                }
            }
            zin.close();
        } catch (Exception e) {
            Log.e("Decompress", "unzip", e);
        }
        return totalSize;
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        bar.setProgress(per); //Since it's an inner class, Bar should be able to be called directly
    }

    @Override    
    protected void onPostExecute(Integer... result) {
        Log.i("Completed. Total size: " + result);
    }
}


回答2:

AsyncTask is a good idea. Should look like this:

private class RunningAlternativSearchAlways extends
        AsyncTask<Integer, Integer, Void> {


    final ProgressDialog dialog = new ProgressDialog(SearchResult.this) {
        @Override
        public boolean onSearchRequested() {
            return false;
        }
    };



    @Override
    protected void onPreExecute() {
        String DialogTitel = getString(R.string.daten_wait_titel);
        DialogText = getString(R.string.dialog_alternativalways_text);
        sucheNach = getString(R.string.dialog_suche_nach);
        dialog.setCancelable(true);
        dialog.setTitle(DialogTitel);
        dialog.setIcon(R.drawable.icon);
        dialog.setMessage(DialogText);
        dialog.setOnDismissListener(new OnDismissListener() {
            public void onDismiss(DialogInterface arg0) {
                // TODO Auto-generated method stub
                cancleBarcodeWorker();
            }
        });
        dialog.show();
    }

    public void cancleBarcodeWorker() {
        try {
            this.cancel(true);
        } catch (Exception ex) {

        }
    }

    @Override
    protected void onCancelled() {
        dialog.cancel();
        Toast toast = Toast.makeText(SearchResult.this, SearchResult.this
                .getString(R.string.toast_suche_abgebrochen),
                Toast.LENGTH_LONG);
        toast.show();
    }

    @Override
    protected Void doInBackground(Integer... param) {
        // UNZIP YOUR FILE HERE

        // PUBLISH YOUR PROGRESS LIKE THIS
        publishProgress(0, i);
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        switch (values[0]) {
        case 0:
            // Suchbegriffe einzeln analysieren
            dialog.setMessage(DialogText + "\n" + sucheNach + " "
                    + suchBegriffe[values[1]]);
            break;
        }
    }

    @Override
    protected void onPostExecute(Void result) {
        // CLOSE YOUR DIALOG HERE
        dialog.cancle();
    }
}


回答3:

In Android, you have one UI thread, and as many other background threads as you want. Only one task can be done on the UI thread at any given moment. As you are unzipping the file on the UI thread, it blocks any other operations, like those concerning the progress dialog. Android provides an AsyncTask that easily allows you to do work in background, while also posting updates onto the UI thread.

Try using an AsyncTask to create, setup and display your dialog in onPreExecute(), unzip the file and publish the progress in doInBackground(), display the updates in onProgressUpdate() and dismiss the dialog in onPostExecute()