我正在使用ProgressBar
在我的 Android 应用中提取数据库时显示的值,但ProgressBar
值超过100且显示为 122%< / strong>
我尝试过设置,
if(progress<=100)
publishProgress(progress);
但这导致长时间显示100%。
任何人都可以帮助计算进度,并回复文件大小和提取。
这是我的代码:
@Override
protected Integer doInBackground(Void... params) {
byte[] buf = new byte[8192];
String name = null;
try {
System.out.println("doInBackground");
listener.onDoInBackground(context,true);
name = "db_sqlite.7z";
//InputStream of the sqlite file
InputStream in = context.getResources().openRawResource(R.raw.db_sqlite);
int fileSize = in.available();
FileOutputStream out = context.openFileOutput("db.sqlite", 0);//Context.MODE_PRIVATE);
try {
/* In contrast to other classes in org.tukaani.xz,
LZMAInputStream doesn't do buffering internally
and reads one byte at a time. BufferedInputStream
gives a huge performance improvement here but even
then it's slower than the other input streams from
org.tukaani.xz.
in = new BufferedInputStream(in); */
in = new XZInputStream(in);
int size;
int counter=0;
while ((size = in.read(buf)) != -1) {
//System.out.write(buf, 0, size);
if(this.isCancelled())
break;
out.write(buf, 0, size);
counter++;
progress = (int) (counter*100*1024/(double)fileSize);
publishProgress(progress);
}
protected void onProgressUpdate(Integer... values) {
//System.out.println("onProgressUpdate");
super.onProgressUpdate(values);
listener.onProgressUpdation(context, true, values);
}
在一项活动中:
@Override
public void onProgressUpdation(Context context, Boolean isStarted, Integer... values) {
tv_you_can_change.setText(context.getResources().getString(R.string.extracting_database) + " " + values[0] + "%");
tv_you_can_change.setVisibility(View.VISIBLE);
progressBar.setProgress(values[0]);
//System.out.println("onProgressUpdation");
}
答案 0 :(得分:1)
InputStream.available()不返回总字节数,它返回可以无阻塞地读取的字节数的估计值。
在这种情况下确定总大小没有很好的方法。但是,由于它是一个资源,因此您知道编译时的大小,并且它在运行时不会更改。因此,只需将大小存储在Number资源中(如果必须,则将其硬编码)。
要确定读取的字节数,请保持in.read()返回的运行总数 然后,进度只是bytesRead / fileSize。
答案 1 :(得分:0)
试试这个:
@Override
protected Integer doInBackground(Void... params) {
byte[] buf = new byte[8192];
String name = null;
try {
System.out.println("doInBackground");
listener.onDoInBackground(context,true);
name = "db_sqlite.7z";
//InputStream of the sqlite file
InputStream in = context.getResources().openRawResource(R.raw.db_sqlite);
int fileSize = in.available();
FileOutputStream out = context.openFileOutput("db.sqlite", 0);//Context.MODE_PRIVATE);
try {
/* In contrast to other classes in org.tukaani.xz,
LZMAInputStream doesn't do buffering internally
and reads one byte at a time. BufferedInputStream
gives a huge performance improvement here but even
then it's slower than the other input streams from
org.tukaani.xz.
in = new BufferedInputStream(in); */
in = new XZInputStream(in);
int size;
int counter=0;
while ((size = in.read(buf)) != -1) {
//System.out.write(buf, 0, size);
if(this.isCancelled())
break;
out.write(buf, 0, size);
counter++;
progress = (int) (counter/(double)fileSize*100);
publishProgress(progress);
}
protected void onProgressUpdate(Integer... values) {
//System.out.println("onProgressUpdate");
super.onProgressUpdate(values);
listener.onProgressUpdation(context, true, values);
}
答案 2 :(得分:0)
是的,我找到了路!
//Original file size i.e size after extraction
float fileSize = 160088064;
提取后硬编码文件大小...
try {
// In contrast to other classes in org.tukaani.xz,
// LZMAInputStream doesn't do buffering internally
// and reads one byte at a time. BufferedInputStream
// gives a huge performance improvement here but even
// then it's slower than the other input streams from
// org.tukaani.xz.
//in = new BufferedInputStream(in);
in = new XZInputStream(in);
int size;
int counter=0;
while ((size = in.read(buf)) != -1) {
if(this.isCancelled())
break;
out.write(buf, 0, size);
counter++;
//System.out.println((counter*8192)/fileSize);
progress = (int) (((counter*bufferSize)/fileSize)*100);
publishProgress(progress);
}
感谢大家帮忙找到了......