Boooil's BLOG.

图像特征匹配开发手记Vol_7

2021/02/01 Share

AsyncTask的使用


AsyncTask是Android中的一个封装好的轻量级异步类

1
2
3
4
5
6
7
8
9
10
11
12
13
public abstract class AsyncTask<Params, Progress, Result> { 
...
// 类中参数为3种泛型类型
// 整体作用:控制AsyncTask子类执行线程任务时各个阶段的返回类型
// 具体说明:
// a. Params:开始异步任务执行时传入的参数类型,对应excute()中传递的参数
// b. Progress:异步任务执行过程中,返回下载进度值的类型
// c. Result:异步任务执行完成后,返回的结果类型,与doInBackground()的返回值类型保持一致
// 注:
// a. 使用时并不是所有类型都被使用
// b. 若无被使用,可用java.lang.Void类型代替
// c. 若有不同业务,需额外再写1个AsyncTask的子类
}

主要作用是实现多线程,实现工作现成和主线程(UI线程)之间的通信。

在匹配过程中,一般需要多次进行匹配获取相关数据,如果直接在OnCreate()函数中进行匹配函数的调用,会使主线程任务处理过多导致黑屏。所以引入AsyncTask进行耗时任务的处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
private class MyAsyncTask extends AsyncTask<Void, Integer,Double>{
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Double doInBackground(Void... voids) {
String TestFile_Path = "";
Bitmap src_bitmap2= BitmapFactory.decodeStream(getClass().getResourceAsStream("/assets/pic_set/2/Library_1.jpg"));
src_bitmap2 = Bitmap.createScaledBitmap(src_bitmap2,960,540,true);
double sum =0;
int progress =0;//进度条进度
for(int i=1;i<7;i++){
TestFile_Path = "/assets/pic_set/2/BoyDorm_" + i +".jpg";
System.out.println(TestFile_Path);
Bitmap src_bitmap1= BitmapFactory.decodeStream(getClass().getResourceAsStream(TestFile_Path));
src_bitmap1 = Bitmap.createScaledBitmap(src_bitmap1,960,540,true);
FeatureMatch featureMatch = new FeatureMatch();
sum += featureMatch.Score(src_bitmap1,src_bitmap2);
progress += 1;
publishProgress(progress);
}
sum = sum/6;
System.out.println("得分:"+sum);
return sum;
}

@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressBar.setProgress(values[0]);
}

@Override
protected void onPostExecute(Double aDouble) {
super.onPostExecute(aDouble);
String s = Double.toString(aDouble);
score.setText(s);
}
}

这里先写了一个测试Task,doInBackground的参数是Void,onProgressUpdate的参数是Int,onPostExecute的参数是Double。

因为是测试用的,逻辑并不完善。测试使用一张图书馆的图片和六张男生寝室楼的图片进行比对,这里引入了一个ProgressBar(进度条),将进度条的总长度设为6,当前进度为0,每进行一次完比对进度+1,更新进度条。publishProgress()函数是doInBackground和onProgressUpdate之间传递参数的函数。

最后onPostExecute返回平均分数。

使用AsyncTask后activity在进行匹配任务时UI界面不会出现黑屏现象。


需要解决的问题:

  • 获取区域文件夹下的图片总数,用以确定匹配轮数和更新进度条总长度。doInBackground进程不能对进度条总长度进行变化,必须得在UI进程下,所以考虑单独写一个更新进度条的方法。
  • 将一个区域文件夹建筑区分开来。目前思路:对下划线前的字符串进行比对,相同的放在一个list中,以便获得不同的分数。在区域文件下下再设立单独的建筑文件夹也可,需要考虑一下。
  • 准确率还是一个问题,感觉时好时不好。