1

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 enter image description here

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();


    }
}
Nicola Gallazzi
  • 7,897
  • 6
  • 45
  • 64
wisam
  • 57
  • 1
  • 12
  • 1
    post stacktrace – John Joe Apr 18 '19 at 08:20
  • Are you updating the ui in the search method? Post the complete code and the error given by the logcat – Nicola Gallazzi Apr 18 '19 at 08:22
  • Possible duplicate of [Unfortunately MyApp has stopped. How can I solve this?](https://stackoverflow.com/questions/23353173/unfortunately-myapp-has-stopped-how-can-i-solve-this) – Vladyslav Matviienko Apr 18 '19 at 08:25
  • @NicolaGallazzi yes I am updating the ui in the search method is this the problem ? – wisam Apr 18 '19 at 08:41
  • what is RGBtoGrey class? ProgressDialog need the context of the activity, same as: public BackgroundTaskSearch(MainActivity activity) { dialog = new ProgressDialog(activity); } – Cuong Nguyen Apr 18 '19 at 08:43
  • @wisam you shouldn't update the ui in a background thread. In android ui can only be updated in the main thread. Use onProgressUpdate method to update the ui – Nicola Gallazzi Apr 18 '19 at 08:44
  • @CườngNguyễn this is the name of the activity it was a testing activity – wisam Apr 18 '19 at 08:44
  • Can you public function "search"?, I think the problem is here – Cuong Nguyen Apr 18 '19 at 08:58
  • @NicolaGallazzi I moved the line "adapter.notifyDataSetChanged();" from the search() method which is in the doInBackground and put it in the search button action after executing task but it did not work, knowing that adapter.notifyDataSetChanged(); is for updating the listView which is custom listView – wisam Apr 18 '19 at 09:00

1 Answers1

2

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

Nicola Gallazzi
  • 7,897
  • 6
  • 45
  • 64
  • Thank you very much Nicola, i was updating the UI in doInBackground other than adapter.notifydatasetchnage i was set textview but I did not pay attention to that at first, so when I removed all codes that update the UI from doInBackground to main thread like onPostExecute it works 100%, again thank you very much – wisam Apr 18 '19 at 12:18