Issue
I have in my application a time consuming task which takes some minutes to finish. The task is about image matching using ORB algorithm, an image query is compared with all images in gallery and then return similar images to listView, due to long time that the task takes, I prefer to add a progress Dialog with Asynctask. The problem is that when I press the search button the progress Dialog appears for long time and then the app crashes, so it seems that when the process is finished the app is crashed instead of hiding the progress dialog and showing results in listview.( knowing that the code works normally without progress Dialog and asynctask ). ALso i tried it using thread and same problem. Any help will be highly appreciated. Thanks in advance
Search Button Code:
searchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
BackgroundTaskSearch task = new BackgroundTaskSearch(RGBtoGrey.this);
task.execute();
}
});
AsyncTask Code:
private class BackgroundTaskSearch extends AsyncTask <Void, Void, Void> {
private ProgressDialog dialog;
public BackgroundTaskSearch(RGBtoGrey activity) {
dialog = new ProgressDialog(activity);
}
@Override
protected void onPreExecute() {
dialog.setMessage("Doing something, please wait.");
dialog.setCanceledOnTouchOutside(false);
dialog.show();
}
@Override
protected void onPostExecute(Void result) {
if (dialog.isShowing()) {
dialog.dismiss();
/* try
{
dialog.dismiss();
}
catch (Exception e)
{
}*/
}
}
@Override
protected Void doInBackground(Void... params) {
search(); // Calling method of the long time task
return null;
}
}
locat: line (RGBtoGrey.java:1030) is dialog.show(); in the onPreExecute() and the line (RGBtoGrey.java:331) is task.execute(); in the search button action
search() method code:
public void search(){
Mat qmat = new Mat();
Mat jsonmat =null;
String q = qtag.getText().toString().trim();
if (!searchType.equals("byImage") && (q.isEmpty() || q.length() == 0 || q.equals("") || q == null)) {
Toast.makeText(getApplicationContext(), "Please insert image or tag", Toast.LENGTH_LONG).show();
} else {
if(!searchType.equals("byImage")) {
DataBaseHandler db2 = new DataBaseHandler(getApplicationContext());
List<image> list = db2.getImages(q);
for (int i = 0; i < list.size(); i++) {
imageList.add(list.get(i));
}
if (imageList.size() != 0 && imageList.size() > 1)
t.setText(Integer.toString(imageList.size()) + " images found");
if (imageList.size() != 0 && imageList.size() == 1)
t.setText(Integer.toString(imageList.size()) + " image found");
if (imageList.size() == 0)
t.setText("No result");
adapter.notifyDataSetChanged();
}
if (TYPE.equals("gallery")) {
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
Bitmap qbitmap0 = BitmapFactory.decodeFile(picPath, bmOptions);
Bitmap qbitmap = getRotated(qbitmap0, picPath);
Mat qmatRGB = new Mat();
Utils.bitmapToMat(qbitmap, qmatRGB);
Imgproc.cvtColor(qmatRGB, qmat, Imgproc.COLOR_RGB2GRAY);
org.opencv.core.Size s = new Size(3, 3);
Imgproc.GaussianBlur(qmat, qmat, s, 2);
}
if (TYPE.equals("camera")) {
Mat qmatRGB = new Mat();
Utils.bitmapToMat(photo, qmatRGB);
Imgproc.cvtColor(qmatRGB, qmat, Imgproc.COLOR_RGB2GRAY);
org.opencv.core.Size s = new Size(3, 3);
Imgproc.GaussianBlur(qmat, qmat, s, 2);
}
ArrayList<String> pathArray = getFilePaths();
DataBaseHandler db = new DataBaseHandler(getApplicationContext());
List<mat> matlist =db.getAllMats();
FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
detector.detect(qmat, keypoints1);
DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.ORB);
Mat descriptors1 = new Mat();
extractor.compute(qmat, keypoints1, descriptors1);
for (int i = 0; i < pathArray.size(); i++) {
BitmapFactory.Options bmOptions1 = new BitmapFactory.Options();
Bitmap bitmap0 = BitmapFactory.decodeFile(pathArray.get(i).toString(), bmOptions1);
Bitmap bitmap = getRotated(bitmap0, pathArray.get(i).toString());
Mat mat = new 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);
mat m =matlist.get(i);
String smat = m.getMat();
String smatkey = m.getMatimage();
Mat descriptors2 = matFromJson(smat);
Mat keypoints2 = keypointsFromJson(smatkey);
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
MatOfDMatch matches = new MatOfDMatch();
matcher.match(descriptors1, descriptors2, matches);
List<DMatch> matchesList = matches.toList();
List<DMatch> matches_final = new ArrayList<DMatch>();
for (int j = 0; j < matchesList.size(); j++)
if (matchesList.get(j).distance <= DIST_LIMIT) {
matches_final.add(matches.toList().get(j));
}
List<MatOfDMatch> matcheslis = new ArrayList<MatOfDMatch>();
matcher.knnMatch(descriptors1, descriptors2,
matcheslis, 2);
ArrayList<KeyPoint> objectPoints = new ArrayList<KeyPoint>(), imagePoints = new ArrayList<KeyPoint>();
for (MatOfDMatch match : matcheslis) {
DMatch[] dmatches = match.toArray();
if (dmatches.length == 2
&& dmatches[0].distance < dmatches[1].distance * 0.75) {
imagePoints
.add(keypoints1.toArray()[dmatches[0].queryIdx]);
objectPoints
.add(((MatOfKeyPoint) keypoints2).toArray()[dmatches[0].trainIdx]);
}
}
float ratio = ((float) objectPoints.size())
/ ((float) keypoints2.size().width);
// ration>=12
if (ratio >= 16 || matches_final.size() >= 147) {
image Image = new image();
Image.setImageURL(pathArray.get(i).toString());
Image.setGoodMatches(matches_final.size());
Image.setRatio(ratio);
imageList.add(Image);
}
}
for (int k = 0; k < imageList.size(); k++) {
if (imageList.get(k).getImageURL().equals(picPath))
imageList.remove(k);
}
if (imageList.size() != 0 && imageList.size() > 1)
t.setText(Integer.toString(imageList.size()) + " images found");
if (imageList.size() != 0 && imageList.size() == 1)
t.setText(Integer.toString(imageList.size()) + " image found");
if (imageList.size() == 0)
t.setText("No result");
adapter.notifyDataSetChanged();
}
}
Solution
As far as I can see from your code, you're trying to update your UI in the doInBackground
method. doInBackground
runs in a worker thread and in android you can update the UI only in the main thread. Do your long time job in the doInBackground
method but update your UI in a main thread method, like for example onProgressUpdate
or onPostExecute
. More info about asynctask here
Answered By - Nicola Gallazzi
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.