3

我正在尝试 progress bar通过解压缩 sd 卡中的文件来更新 a。我的解压缩工作正常,但progress bar没有出现。这是我在 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();     
            }   
        }

    }
}
4

3 回答 3

9

您的解压缩代码在 Main/UI 线程上运行,从而冻结了 UI。您想在后台线程中使用AsyncTask.

您的案例示例:

 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);
    }
}
于 2012-08-14T07:22:25.950 回答
1

在 Android 中,您有一个 UI 线程,以及任意数量的其他后台线程。在任何给定时刻,只能在 UI 线程上完成一项任务。当您在 UI 线程上解压缩文件时,它会阻止任何其他操作,例如与进度对话框有关的操作。Android 提供了一个AsyncTask,它可以轻松地让您在后台工作,同时还可以将更新发布到 UI 线程。

尝试使用 AsyncTask 在 onPreExecute() 中创建、设置和显示对话框解压缩文件并在doInBackground()中发布进度,在onProgressUpdate()中显示更新并在onPostExecute()中关闭对话框

于 2012-08-14T07:37:32.113 回答
0

AsyncTask 是个好主意。应该是这样的:

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();
    }
}
于 2012-08-14T07:22:26.563 回答