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?
}
});
3
Answers
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
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.
NOTE: Make sure execution never goes to infinite loop.
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 aThread
"by hand". This also allows you to return a value from your job in which case you submit aCallable<?>
instead of aRunnable
.You can also start a thread and then
join()
with it. That waits for the thread to finish.The
get()
method or thejoin()
method also means that theexistingCountDates
or anything else that was modified inside of the job will be updated in the caller’s memory appropriately.