android - 运行代码时显示进度对话框的问题
问题描述
我试图在执行长时间运行的代码时显示一个带有百分比的进度对话框,我为此使用了 AsyncTask 但它不起作用,功能如下:我获取所有画廊图像的数组路径,然后处理这些图像并提取每个图像的描述符向量并将其转换为 JSON 字符串,然后将这些字符串存储到 sqlite,但我的代码需要很多时间(几分钟),所以我需要显示一个带有百分比的进度对话框以便知道任务的开始和结束,这个任务我需要在按下按钮时启动它。下面是我的代码:
public void FillDataBase(){
ArrayList<String> paths = getFilePaths();
for (int i = 0; i < paths.size(); i++) {
Mat mat = new Mat();
BitmapFactory.Options bmOptions1 = new BitmapFactory.Options();
//bmOptions1.inSampleSize=4;
Bitmap bitmap0 = BitmapFactory.decodeFile(paths.get(i).toString(), bmOptions1);
Bitmap bitmap = getRotated(bitmap0, paths.get(i).toString());
//Utils.bitmapToMat(bitmap, mat);
Mat matRGB = new Mat();
Utils.bitmapToMat(bitmap, matRGB);
Imgproc.cvtColor(matRGB, mat, Imgproc.COLOR_RGB2GRAY);
org.opencv.core.Size s2 = new Size(3, 3);
Imgproc.GaussianBlur(mat, mat, s2, 2);
FeatureDetector detector2 = FeatureDetector.create(FeatureDetector.ORB);
MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
detector2.detect(mat, keypoints2);
DescriptorExtractor extractor2 = DescriptorExtractor.create(DescriptorExtractor.ORB);
Mat descriptors2 = new Mat();
extractor2.compute(mat, keypoints2, descriptors2);
// String matimage = matToJson(mat);
String matkeys= keypointsToJson(keypoints2);
String desc = matToJson(descriptors2);
mat m = new mat(desc, matkeys);
DataBaseHandler db = new DataBaseHandler(getApplicationContext());
db.addmat(m);
}
Asynctask 代码(我在线程的公共 void 运行中调用 FillDatabase()):
private class ProgressTask extends AsyncTask<Void,Void,Void>{
private int progressStatus=0;
private Handler handler = new Handler();
// Initialize a new instance of progress dialog
private ProgressDialog pd = new ProgressDialog(RGBtoGrey.this);
@Override
protected void onPreExecute(){
super.onPreExecute();
pd.setIndeterminate(false);
// Set progress style horizontal
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
// Set the progress dialog background color
pd.getWindow().setBackgroundDrawable(new ColorDrawable(Color.YELLOW));
// Make the progress dialog cancellable
pd.setCancelable(true);
// Set the maximum value of progress
pd.setMax(100);
// Finally, show the progress dialog
pd.show();
}
@Override
protected Void doInBackground(Void...args){
// Set the progress status zero on each button click
progressStatus = 0;
// Start the lengthy operation in a background thread
new Thread(new Runnable() {
@Override
public void run() {
FillDataBase();
while(progressStatus < 100){
// Update the progress status
progressStatus +=1;
// Try to sleep the thread for 20 milliseconds
try{
Thread.sleep(20);
}catch(InterruptedException e){
e.printStackTrace();
}
// Update the progress bar
handler.post(new Runnable() {
@Override
public void run() {
// Update the progress status
pd.setProgress(progressStatus);
// If task execution completed
if(progressStatus == 100){
// Dismiss/hide the progress dialog
pd.dismiss();
}
}
});
}
}
}).start(); // Start the operation
return null;
}
protected void onPostExecute(){
// do something after async task completed.
}
最后我这样调用 Asynctask:
testButton0.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new ProgressTask().execute();
}
});
解决方案
你可以这样做:
private static class InsertAllPersonsToFirebaseTask extends AsyncTask<Void, Float, Void> {
private List<Person> personList;
private ElasticDownloadView mElasticDownloadView;
private DatabaseReference mDatabase, pushedKey;
private Person person;
public InsertAllPersonsToFirebaseTask(List<Person> personList, ElasticDownloadView mElasticDownloadView) {
this.personList = personList;
this.mElasticDownloadView = mElasticDownloadView;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
if (mElasticDownloadView != null) {
this.mElasticDownloadView.setVisibility(View.VISIBLE);
this.mElasticDownloadView.startIntro();
}
}
@Override
protected Void doInBackground(Void... voids) {
mDatabase = FirebaseDatabase.getInstance().getReference();
for (int i = 0; i < personList.size(); i++){
pushedKey = mDatabase.child("Persons").push();
person = new Person();
person.setPersonId(System.currentTimeMillis());
person.setName(personList.get(i).getName());
pushedKey.setValue(person);
//This line is for update the onProgressUpdate() method
publishProgress(((i+1)/(float)personList.size()* 100));
if (isCancelled()){
break;
}
}
return null;
}
@Override
protected void onProgressUpdate(Float... progress) {
if (mElasticDownloadView != null){
mElasticDownloadView.setProgress(progress[0]);
}
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (mElasticDownloadView != null){
mElasticDownloadView.setVisibility(View.GONE);
}
}
}
您可以使用任何类型的进度条。我使用了 ElasticDownloadview 进度条。
然后:
testButton0.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new InsertAllPersonsToFirebaseTask(personArrayList,mElasticDownloadView).execute();
}
});
推荐阅读
- visual-foxpro - 了解 Foxpro IF 语句
- bash - 添加用户的脚本,然后显示消息是否已创建
- sql - 查找链中的最后一条记录 - 客户合并流程
- c# - Unity Network Discovery 广播非常不一致,但重新安装后有效(Android)
- function - 如何通过反射将函数声明为类型?
- c# - 如何保存 Windows 程序的电子邮件/密码组合?
- python - 有效地合并 pandas 中的子序列
- python - 重定向加载旧内容?
- hadoop-yarn - flink web.port在yarn模式下无法正确配置
- angular - 这
标签限制了表单的宽度,与容器的宽度不匹配