如何观察数据库中的更改以更新LiveData [英] How to observe changes in database in order to update LiveData

查看:500
本文介绍了如何观察数据库中的更改以更新LiveData的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将应用程序从具有CallbacksLoaderManager迁移到使用ViewModelLiveData的实现.我想继续使用现有的SQLiteDatabase.

I am migrating an app from a LoaderManager with Callbacks to an implementation using ViewModel and LiveData. I would like to keep using the existing SQLiteDatabase.

主要实现正常. Activity实例化ViewModel并创建Observer,如果它观察到驻留在ViewModel中的MutableLiveData中的变化,则该Observer将更新View. ViewModel使用ContentProvider通过查询从SQLiteDatabase获取数据(光标).

The main implementation works OK. The Activity instantiates the ViewModel and creates an Observer which updates the View if it observes changes in the MutableLiveData that lives in the ViewModel. The ViewModel gets it data (cursor) from the SQLiteDatabase through a query using a ContentProvider.

但是我有其他活动可以更改数据库,而MainActivity已停止但未被破坏.还有一个后台服务,可以在MainActivity处于前台时对数据库进行更改.

But I have other activities that can make changes to the database, while MainActivity is stopped but not destroyed. There is also a background service that can make changes to the database while the MainActivity is on the foreground.

其他活动和后台服务可以更改数据库中的值,因此可以影响ViewModel中的MutableLiveData.

Other activities and the background service can change values in the database and therefore can have an effect to the MutableLiveData in the ViewModel.

我的问题是:如何观察SQLiteDatabase中的变化以更新LiveData?

My question is: How to observe changes in the SQLiteDatabase in order to update LiveData?

这是MainActivity的简化版本:

public class MainActivity extends AppCompatActivity {
    private DrawerAdapter mDrawerAdapter;
    HomeActivityViewModel homeActivityViewModel;

    private Observer<Cursor> leftDrawerLiveDataObserver = new Observer<Cursor>() {
        @Override
        public void onChanged(@Nullable Cursor cursor) {
            if (cursor != null && cursor.moveToFirst()) { // Do we have a non-empty cursor?
                mDrawerAdapter.setCursor(cursor);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        homeActivityViewModel = ViewModelProviders.of(this).get(HomeActivityViewModel.class);
        homeActivityViewModel.getLiveData().observe(this, leftDrawerLiveDataObserver);
        homeActivityViewModel.updateLiveData(); //,LEFT_DRAWER_LIVEDATA_ID);
    }

    @Override
    protected void onResume(){  // update the LiveData on Resume
        super.onResume();
        homeActivityViewModel.updateLiveData();
    }
}

这是我的ViewModel:

public class HomeActivityViewModel extends AndroidViewModel {

    public HomeActivityViewModel(Application application) {
        super(application);
    }

    @NonNull
    private final MutableLiveData<Integer> updateCookie = new MutableLiveData<>();

    @NonNull
    private final LiveData<Cursor> cursorLeftDrawer =
            Transformations.switchMap(updateCookie,
                    new Function<Integer, LiveData<Cursor>>() {
                        private QueryHandler mQueryHandler;

                        @Override
                        public LiveData<Cursor> apply(Integer input) {
                            mQueryHandler = new QueryHandler(getApplication().getContentResolver());
                            MutableLiveData<Cursor> cursorMutableLiveData = new MutableLiveData<>();
                            mQueryHandler.startQuery(ID, cursorMutableLiveData, URI,
                                new String[]{FeedData.ID, FeedData.URL},
                                null,null,null
                            );
                            return cursorMutableLiveData;
                        }
                    }
            );

    // By changing the value of the updateCookie, LiveData gets refreshed through the Observer.
    void updateLiveData() {
        Integer x = updateCookie.getValue();
        int y = (x != null) ? Math.abs(x -1) : 1 ;
        updateCookie.setValue(y);
    }

    @NonNull
    LiveData<Cursor> getLiveData() {
        return cursorLeftDrawer;
    }

    /**
     * Inner class to perform a query on a background thread.
     * When the query is completed, the result is handled in onQueryComplete
     */
    private static class QueryHandler extends AsyncQueryHandler {
        QueryHandler(ContentResolver cr) {
            super(cr);
        }
        @Override
        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
            MutableLiveData<Cursor> cursorMutableLiveData = (MutableLiveData<Cursor>) cookie;
                             cursorMutableLiveData.setValue(cursor);

        }
    }

}

推荐答案

也许您应该看看Room. Room数据库在后台使用SQLite,并且在数据库中进行任何更改时,它将自动通知您的LiveData对象.因此,您无需担心查询和游标等. 看看这个教程

Maybe you should take a look Room. A Room database uses SQLite in the background and will automatically notify your LiveData objects when any changes have been made in the database. Thus you never need to worry about queries and cursors and so on. Take a look at this tutorial!

这篇关于如何观察数据库中的更改以更新LiveData的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆