Сбой приложения при использовании ProgressDialog в AsyncTask

1

В моем заявлении есть трудоемкая задача, выполнение которой занимает несколько минут. Задача состоит в сопоставлении изображений с использованием алгоритма ORB, запрос изображения сравнивается со всеми изображениями в галерее, а затем возвращаются похожие изображения в listView, из-за долгого времени выполнения задачи я предпочитаю добавлять диалог прогресса с Asynctask. Проблема заключается в том, что когда я нажимаю кнопку поиска, диалоговое окно прогресса появляется в течение длительного времени, а затем приложение аварийно завершает работу, поэтому кажется, что, когда процесс завершается, приложение не работает, вместо того, чтобы скрывать диалоговое окно прогресса и отображать результаты в виде списка. что код работает нормально без прогресса Dialog и asynctask). Также я попробовал это, используя поток и ту же проблему. Любая помощь будет высоко оценена. заранее спасибо

Код кнопки поиска:

 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) является dialog.show(); в onPreExecute() и строке (RGBtoGrey.java:331) есть task.execute(); в действии кнопки поиска Изображение 174551

код метода search():

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


    }
}
Теги:
android-asynctask
progressdialog
crash

2 ответа

2
Лучший ответ

Насколько я вижу из вашего кода, вы пытаетесь обновить свой интерфейс в методе doInBackground. doInBackground запускается в рабочем потоке, а в Android вы можете обновить пользовательский интерфейс только в основном потоке. doInBackground долгую работу в методе doInBackground но обновляйте свой интерфейс в методе основного потока, например, onProgressUpdate или onPostExecute. Подробнее об асинктаске здесь

  • 0
    Большое спасибо, Никола, я обновлял пользовательский интерфейс в doInBackground, кроме адаптера. Notifydatasetchnage. Мне было задано textview, но я сначала не обращал на это внимания, поэтому, когда я удалил все коды, которые обновляют пользовательский интерфейс из doInBackground, в основной поток, например onPostExecute это работает на 100%, еще раз большое спасибо
0

Не могли бы вы упомянуть трассировку стека, которая печатается во время сбоя? Это может помочь нам точно определить проблему.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню