ProgressDialog not shown in AsyncTask

2019-08-05 11:40发布

I have a huge database (40MB) on an SDCard. I need fetch data, with LIKE in query, which is very slow.

DB request takes about 5 seconds. Therefore, I need to do it asynchronously and with ProgressDialog.

I tried it with AsyncTask, but problem is with ProgressDialog.
It was implemented this way:

private class GetDataFromLangDB extends AsyncTask<String, String, String> {

    private final ProgressDialog dialog = new ProgressDialog(TranslAndActivity.this);

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

         urDBCursor.close();
         curDBCursor = null;
         scaAdapter = null;

         this.dialog.setMessage("Loading data...");
         this.dialog.show();

    } 

    @Override
    protected String doInBackground(String... whatSearch) {
        String result = "";

        if (myDatabaseAdapter != null) {
            curDBCursor = myDatabaseAdapter.fetchAll(whatSearch[0]);
        }
        return result;
    }

    @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);

            if (this.dialog.isShowing()) {
                this.dialog.dismiss();
            }

            prepareListView();
    }
}

The problem is that ProgressDialog is not shown during the DB request. After finished database query, it flash on screen for a short time. When user tries to tap on screen during database request, UI is freezed, and after DB request message about 'not responding' is shown.

I tried it with a thread this way:

public void startProgress(View view, final String aWhatSearch) {

        final ProgressDialog dialog = new ProgressDialog(MyActivity.this);
        if (curDBCursor != null){
            curDBCursor.close();
            curDBCursor = null;
        }

        dialog.setMessage("Loading data...");
        dialog.show();
        Runnable runnable = new Runnable() {
            public void run() {
                curDBCursor = myDatabaseAdapter.fetchAll(aWhatSearch);
                // dirty trick
                try {
                    Thread.sleep(250); // it must be here to show progress
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                handler.post(new Runnable() {
                    public void run() {
                        if (dialog.isShowing()) {
                            dialog.dismiss();
                        }
                        prepareListView();
                    }
                });

            }
        };
        new Thread(runnable).start();
    }

The result was the same, but when I used the trick with Thread.sleep(250); ProgressDialog was shown during the database request. But it is not spinning, it looks freezed during the DB request.

DB stuff is called this way (after tap on search button):

btnSearchAll.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        // AsyncTask
        new GetDataFromLangDB().execute(edtTextToSearch.getText().toString());

        // or Thread 
        //startProgress(null, edtTextToSearch.getText().toString());
    }
});

I found a lot of problems like this in SO, but nothing was useful for me. Could it be that DB is on SD Card?

3条回答
混吃等死
2楼-- · 2019-08-05 12:23

I put the definition of the dialog into the AsyncTask Class and it works fine for me. Take a look at this exampel (You have to change NAMEOFCLASS in the name of your CLASS:

private class doInBackground extends AsyncTask<Integer, Integer, Void> {

   final ProgressDialog dialog = new ProgressDialog(NAMEOFCLASS.this) {

    @Override
    protected void onPreExecute() {
        dialog.setCancelable(false);
        dialog.setTitle(getString(R.string.daten_wait_titel));
        dialog.setIcon(R.drawable.icon);
        dialog.setMessage(getString(R.string.dse_dialog_speichern));
        dialog.show();
    }

    @Override
    protected void onCancelled() {
        dialog.cancel();
    }

....

    @Override
    protected void onProgressUpdate(Integer... values) {
                   // DO YOUR UPDATE HERE
    }

    @Override
    protected void onPostExecute(Void result) {
        dialog.dismiss();
                }

}
查看更多
乱世女痞
3楼-- · 2019-08-05 12:25

Maybe this SO answer could help you. It looks like similar problem. Try to use AsyncQueryHandler for querying your database

查看更多
何必那么认真
4楼-- · 2019-08-05 12:34

declare you Dialog box on Class (Activity) level like this

private ProgressDialog dialog = null;

show the progress dialog and call the AsyncTask class when you want to start you Busy work..like onButton click or any

dialog = ProgressDialog.show(this,"Sending Email to your account please! wait...", true);
SendingEmailTask task = new SendingEmailTask();
String s = "";
task.execute(s);

create your inner class like

private class SendingEmailTask extends AsyncTask<String, Void, String> {

    protected String doInBackground(String... urls) {
         //do your work here..
         // like fetching the Data from DB or any
         return null;
       }

       @Override
       protected void onPostExecute(String str) {
           //hide progress dialog here
           dialog.dismiss();
       }
}

let me know if this help!!

查看更多
登录 后发表回答