我正在尝试更新a
progress bar
在SD卡中解压缩文件。我的解压缩工作正常,但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();
}
}
}
}
答案 0 :(得分:7)
您的解压缩代码在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);
}
}
答案 1 :(得分: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();
}
}
答案 2 :(得分:0)
在Android中,您有一个UI线程,以及您想要的许多其他后台线程。在任何给定时刻,只能在UI线程上完成一项任务。当您在UI线程上解压缩文件时,它会阻止任何其他操作,例如有关进度对话框的操作。 Android提供了一个AsyncTask,可以让您轻松地在后台工作,同时还可以在UI线程上发布更新。
尝试使用AsyncTask在onPreExecute()中创建,设置和显示对话框,解压缩文件并在doInBackground()中发布进度,在onProgressUpdate()中显示更新并关闭对话框onPostExecute()