3

I'm using AsyncTask to pull data from my firebase and it works, however I'm using an empty while loop to ensure my database finishes it's operation before the Task moves on to the next step. I know in c using an empty while loop drives up CPU usage, and is generally really bad practice. However, when I try to do what I would do in c (call sleep or wait) the program crashes. Is there another way to do this for Android?

protected String doInBackground(String... params) {

            // add a local list of the restaurants found at yelp and a reference for the background thread to process.
            addRes(yelp.getRestaurants());

            // loop through each restaurant and add all the menu items from each one. I think we need to randomize this list later on to provide variety in the app.
            for (int i = 0; i < restNames.size(); i++) {

            firebase = new firebaseHandler("Tastr Items/" + restNames.get(i) + "/Menu");
            System.err.println("Adding Menu Item From ----> " + restNames.get(i));
            firebase.readFromDatabase();

            // Wait for firebase to finish adding new data, I would like to call sleep() here but it crashes the app for some reason.
            while (!firebase.isReaderDone()) {

                // Here his where I want to call sleep until firebase Handler is finished.
                try {
                    wait(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            // second loop to run through each menu item at each restaurant, this would be very inefficient for a huge number, but for now it should be fine if we have less than 100 or so menu items per restaurant.
            for (int j = 0; j < firebase.getReaderList().size(); j++) {

            System.err.println("Adding Menu Item ----> " + firebase.getReaderList().get(j));
            addMenuItem(firebase.getReaderList().get(j));
            firebase.changeReference("Tastr Items/" + restNames.get(i) + "/Menu/" + firebase.getReaderList().get(j) + "/Image Path");

            }
        }

        return null;
    }//doInBackground

Here are the errors

E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
              Process: com.smileyface.tastr, PID: 5863
              java.lang.RuntimeException: An error occurred while executing doInBackground()
                  at android.os.AsyncTask$3.done(AsyncTask.java:325)
                  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
                  at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
                  at java.util.concurrent.FutureTask.run(FutureTask.java:242)
                  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
                  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
                  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
                  at java.lang.Thread.run(Thread.java:761)
               Caused by: java.lang.IllegalMonitorStateException: object not locked by thread before wait()
                  at java.lang.Object.wait(Native Method)
                  at com.smileyface.tastr.Activities.TouchActivity$dataLoader.doInBackground(TouchActivity.java:369)
                  at com.smileyface.tastr.Activities.TouchActivity$dataLoader.doInBackground(TouchActivity.java:346)
                  at android.os.AsyncTask$2.call(AsyncTask.java:305)
                  at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
                  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
                  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
                  at java.lang.Thread.run(Thread.java:761) 
Remixt
  • 597
  • 6
  • 28
  • 1
    can you post the stacktrace for the crash? – Raghunandan Nov 23 '16 at 05:25
  • Sure thing, sorry about that I should have posted it to begin with. – Remixt Nov 23 '16 at 05:25
  • 1
    Check this out http://stackoverflow.com/questions/26590542/java-lang-illegalmonitorstateexception-object-not-locked-by-thread-before-wait – Tasneem Nov 23 '16 at 05:31
  • 1
    A quick search on stackoverflow http://stackoverflow.com/questions/1537116/illegalmonitorstateexception-on-wait-call – Raghunandan Nov 23 '16 at 05:34
  • I need to get better at searching because I spent about an hour looking for an answer before I posted this. Thanks for your links guys I appreciate it! @Tasneem That cleared things up quite a bit, I forgot that you need to have a method that wakes the thread if you are calling wait. It's been awhile since I did that in C. Thank you! – Remixt Nov 23 '16 at 05:34
  • 1
    You canot use thread in aysn task,So you can use runUi to solve the problem – Vadivel Nov 23 '16 at 05:35
  • 1
    Just a tip : the line start's with `Caused by:` in stacktrace is the real reason for your crash and searching that in google will fetch you answers pretty quickly. – Sunil Sunny Nov 23 '16 at 05:39

1 Answers1

2

use countdown timer

 CountDownTimer test=  new CountDownTimer(3000,1000) {

        @Override
        public void onTick(long millisUntilFinished) {
            // do when countdown timer is started like show progressbar

        }

        @Override
        public void onFinish() {

            //write what ever you want to do after completing time like hiding progress bar
        }
    };


    test.start();

here is 1000 is starting time and 3000 is ending time in ms

Manohar
  • 22,116
  • 9
  • 108
  • 144