简体   繁体   English

从线程返回值(可运行)

[英]Return value from thread (runnable)

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. 我正在与Room一起使用来保存数据,使用新的AAC来保存数据,并且我正在开发一个应用程序,其中Google github存储库中提供的Todo应用程序是我们的蓝图。
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. 我使用了全局变量mCategories来检索和存储返回的数据,但我一直在返回一个空对象。

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. 那是因为这里有2个线程
When you call readTransaction() and then mAppExecutors.diskIO().execute(readRunnable) , method readTransaction() returns immediately and calls LOGD(TAG, "sanitizeCategoriesList size after: " + mCategories); 当您调用readTransaction()然后调用readTransaction() mAppExecutors.diskIO().execute(readRunnable) ,方法readTransaction()立即返回并调用LOGD(TAG, "sanitizeCategoriesList size after: " + mCategories); , which as expected prints null . ,按预期打印null In the meantime, asynchronously on second thread, run() is executed, invoking at the end onReadTransactionCompleted() and finally setting mCategories value. 在此期间,异步上第二螺纹, run()被执行时,在结束调用onReadTransactionCompleted()最后设定mCategories值。

So you can only rely on mCategories after onReadTransactionCompleted() was invoked. 因此,仅在调用onReadTransactionCompleted()之后才能依赖于mCategories

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() 如果您将mCategories用于UI相关的内容,则可能要考虑使用AsyncTask并将代码从run()移至doInBackground()并将代码从onReadTransactionCompleted()移至onPostExecute()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM