skip to Main Content

I am using a thread to get an id from my database. Once the thread has finished running I need to use that id in another thread to get a list of items. Once that thread has finished I use the list of items to populate a spinner. The problem I am encountering is that it is populating the spinner before the thread has returned the list of items. How can I make it so the spinner doesn’t get populated until the thread has finished running?

        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

                new Thread(new Runnable() {
                    @Override
                    public void run() {

                        String bookName = existingBooks.get((int) spinner.getSelectedItemId());

                        Book myBook = AppDatabase.getInstance(getContext()).bookDAO().getBookByTitle(bookName);

                        long book_Id = myBook.getBook_id();

                        existingCountDates = AppDatabase.getInstance(getContext()).countDAO().getCountDatesInBook(book_Id);

                        List<Count> Counts = AppDatabase.getInstance(getContext()).countDAO().getAllCounts();

                        Log.e("Dates", existingCountDates.toString());
                        Log.e("All Counts", Counts.toString());

                    }
                }).start();

                //TODO: FIX THIS ISSUE
                Log.e("Problem:", "This gets called before the thread finishes. Not sure how to fix it");
                str_adapter.clear();
                for (int i = 0; i < existingCountDates.size(); i++) {
                    str_adapter.add(existingCountDates.get(i));
                }
                str_adapter.notifyDataSetChanged();

            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                //TODO: DISABLE OTHER DROPDOWN MENUS?
            }
        });

enter image description here

3

Answers


  1. You can use another thread and wait previous thread till finish using thread.join(). bu better version is use ExecutorServices such as for instance the ThreadPoolExecutor.

    CODELAB

    Login or Signup to reply.
  2. I am not sure whether this will help you or not. But you can use a bool variable to check whether the thread has finished its work.

    bool flag = false;
    new Thread(new Runnable() {
        @Override
        public void run() {
            //statements
            flag = true;
        }
    }).start();
    while(flag != true);
    //statements to be executed after completion of thread.
    

    NOTE: Make sure execution never goes to infinite loop.

    Login or Signup to reply.
  3. How can I make it so the spinner doesn’t get populated until the thread has finished running?

    There are a couple of ways to do that. The easiest might be to get an ExecutorService which is usually recommended as opposed to creating a Thread "by hand". This also allows you to return a value from your job in which case you submit a Callable<?> instead of a Runnable.

    ExecutorService threadPool = Executors.newFixedThreadPool(1);
    ...
    Future<Void> future = threadPool.submit(new Runnable() {
        public void run() {
           ...
        }
    });
    // wait for this job to finish
    future.get();
    ...
    // when you are done with the pool you need to shut it down
    threadPool.shutdown();
    

    You can also start a thread and then join() with it. That waits for the thread to finish.

    Thread thread = new Thread(new Runnable() { ... });
    thread.start();
    // now we can do stuff while the thread runs in the background
    ...
    // wait for the thread to finish before returning
    thread.join();
    ...
    

    The get() method or the join() method also means that the existingCountDates or anything else that was modified inside of the job will be updated in the caller’s memory appropriately.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search