1

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?

Peter
  • 269
  • 3
  • 13

3 Answers3

1

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

}
JackTools.Net
  • 734
  • 6
  • 13
  • I think that his definition of the dialog is in AsyncTask. He reference it by using this.dialog – sinisha Aug 17 '12 at 08:30
  • Yes definition of the dialog is in the AsyncTask. Therefore I'm confused what's wrong there. Maybe during the heavy DB load -> device is not responding due to the busy SQLite driver.... **Maybe I need service for this (?) ** – Peter Aug 17 '12 at 08:38
  • Ok. that's right. Then the only diference is the line Super.OnPreExcecute(); Perhaps it will help to delete this line. – JackTools.Net Aug 17 '12 at 08:44
  • @Peter And could you give us the logcat? – sinisha Aug 17 '12 at 08:45
  • @JackTools.Net If he deletes super.OnPreExecute it will definitely crash the application – sinisha Aug 17 '12 at 08:48
  • Well I use the exampe I posted several times and it works fine for ne without this line of code. – JackTools.Net Aug 17 '12 at 09:01
0

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

Community
  • 1
  • 1
sinisha
  • 1,013
  • 13
  • 30
0

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!!

swiftBoy
  • 35,607
  • 26
  • 136
  • 135
  • thanks for an answer, but it did not help. It still the same. I will try sinisha answer with AsyncQueryHandler, or I try to wrap it into a **Service** – Peter Aug 17 '12 at 11:36
  • okay i didn't check with DB loading so not sure about that but i do this for sending email etc and it works fine with me..well good luck with AsyncQueryHandler – swiftBoy Aug 17 '12 at 12:29