Я перемещаю приложение из 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);
}
}
}