简体   繁体   English

运行代码时显示进度对话框的问题

[英]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. 我正在尝试在执行长时间运行的代码时显示一个包含百分比的进度对话框,我为此目的使用了AsyncTask但它没有用,功能如下:我得到所有图库图像的数组路径然后我处理这些图像并提取每个图像的描述符向量并将其转换为JSON字符串然后将这些字符串存储到sqlite中,但我的代码需要花费大量时间(几分钟),因此我需要显示一个包含百分比的进度对话框以便知道任务的开始和结束,这个任务我需要在按下按钮时启动它。 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): Asynctask代码(我在线程的公共void运行中调用FillDatabase()):

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: 最后我像这样调用Asynctask:

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. 我使用过ElasticDownloadview进度条。

Then: 然后:

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

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

                 }

    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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