I'm working with Room to persist data, the new AAC for persisting data, and I work on an app where the Todo app provided in the Google's github repository serves as our blueprint.
I've been trying to get a value returned by a transaction performed on an entity. I used a global variable mCategories
to retrieve and store the data returned but I keep on having a null object being returned.
Here's my code:
public interface LoadDataListener<T>
{
void onReadTransactionCompleted(T arg);
}
private void readTransaction(final LoadDataListener<List<Category>> loadDataListener, final boolean onlyClassic)
{
Runnable readRunnable = new Runnable() {
@Override
public void run() {
List<Category> categories;
if (!onlyClassic)
categories = mCategoryDAO.loadAllSellingCategories();
else
categories = mCategoryDAO.loadAllClassicCategories();
LOGD(TAG, "Category size: "+ categories.size());
// The log above reads a value > 0
loadDataListener.onReadTransactionCompleted(categories);
}
};
mAppExecutors.diskIO().execute(readRunnable);
}
private List<Category> getSanitizedAndPersistedCategories(boolean onlyClassic) {
readTransaction(new LoadDataListener<List<Category>>() {
@Override
public void onReadTransactionCompleted(List<Category> arg) {
mCategories = arg;
LOGD(TAG, "sanitizeCategoriesList size before: " + mCategories);
// The log above reads a value > 0
}
}, onlyClassic);
LOGD(TAG, "sanitizeCategoriesList size after: " + mCategories);
// The log above reads null
return sanitizeCategoriesList(mCategories);
}
What am I missing here ??
That's because you have 2 threads here.
When you call readTransaction()
and then mAppExecutors.diskIO().execute(readRunnable)
, method readTransaction()
returns immediately and calls LOGD(TAG, "sanitizeCategoriesList size after: " + mCategories);
, which as expected prints null
. In the meantime, asynchronously on second thread, run()
is executed, invoking at the end onReadTransactionCompleted()
and finally setting mCategories
value.
So you can only rely on mCategories
after onReadTransactionCompleted()
was invoked.
If you are using mCategories
for UI related stuff, you might wanna consider using AsyncTask and moving your code from run()
to doInBackground()
and code from onReadTransactionCompleted()
to onPostExecute()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.