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();
}
}
}
}
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);
}
}
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();
}
}
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()