简体   繁体   中英

Problem showing progress dialog while running code

I am trying to show a progress dialog with percentage while executing a long running code, I used AsyncTask for this purpose but it did not work, the functionality is as follow: I get the array paths of all gallery images and then I process these images and extract the descriptor vector of each image and convert it to JSON string and then store these strings into sqlite, but my code takes lot of time( few minutes ), so what I need is to show a progress dialog with percentage in order to know the start and end of the task, this task I need to start it when I press a button. Below is my code:

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 Code (I call the FillDatabase() in public void run of the thread):

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.
    }

And finally i call the Asynctask like this:

testButton0.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

        new ProgressTask().execute();

                }

    });

You could do something like this:

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

You can use any type of progressbar. I have used ElasticDownloadview progressbar.

Then:

testButton0.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

         new InsertAllPersonsToFirebaseTask(personArrayList,mElasticDownloadView).execute();

                 }

    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM