3

我正在将应用程序从LoaderManagerwith迁移Callbacks到使用ViewModeland的实现LiveData。我想继续使用现有的SQLiteDatabase.

主要实现工作正常。Activity实例化ViewModel并创建一个Observer更新 的,如果View它观察到 中的MutableLiveData变化ViewModel。通过使用. ViewModel_SQLiteDatabaseContentProvider

但是我有其他可以对数据库进行更改的活动,虽然MainActivity被停止但没有被破坏。还有一个后台服务可以MainActivity在前台更改数据库。

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

我的问题是:如何观察变化SQLiteDatabase以便更新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);

        }
    }

}
4

1 回答 1

0

也许你应该看看RoomLiveDataRoom 数据库在后台使用 SQLite,并在数据库发生任何更改时自动通知您的对象。因此,您永远不需要担心查询和游标等。看看这个教程

于 2018-10-12T19:51:56.167 回答