Как наблюдать изменения в базе данных для обновления LiveData - PullRequest
0 голосов
/ 12 октября 2018

Я перемещаю приложение из LoaderManager с Callbacks в реализацию, используя ViewModel и LiveData.Я хотел бы продолжать использовать существующие SQLiteDatabase.

Основная реализация работает нормально.Activity создает экземпляр ViewModel и создает Observer, который обновляет View, если он наблюдает изменения в MutableLiveData, который живет в ViewModel.ViewModel получает данные (курсор) от SQLiteDatabase через запрос, используя ContentProvider.

Но у меня есть другие действия, которые могут вносить изменения в базу данных, пока 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);

        }
    }

}

1 Ответ

0 голосов
/ 12 октября 2018

Может быть, вам стоит взглянуть Room.База данных Room использует SQLite в фоновом режиме и автоматически уведомляет ваши LiveData объекты, когда в базу данных вносятся какие-либо изменения.Таким образом, вам никогда не нужно беспокоиться о запросах, курсорах и так далее.Взгляните на этот учебник !

...