用MutableLivedata <Cursor>替换getLoaderManager()。initLoader

时间:2019-06-04 14:26:15

标签: android android-room android-architecture-components mutablelivedata

getLoaderManager已在android 28中弃用。ViewModel,存储库和Room替换了加载器功能

我找到2篇文章:

https://medium.com/@JasonCromer/making-room-less-database-queries-using-the-new-android-architecture-components-81180ba6e7e0

https://medium.com/androiddevelopers/lifecycle-aware-data-loading-with-android-architecture-components-f95484159de4

但均未显示如何将光标传递到我的自定义适配器(扩展了RecyclerViewCursorAdapter)。

我的PlaylistViewModel

  public class PlaylistViewModel extends AndroidViewModel {
@NonNull
private  MutableLiveData<Cursor> mLiveData = new MutableLiveData<>() ;
@NonNull
 private final DatabaseQueryRepository mDatabaseRepository;
private LiveData<Cursor> mResult;

public PlaylistViewModel(Application application) {
    super(application);
    mDatabaseRepository = DatabaseQueryRepository.newInstance();
    loadData();
}

private void loadData() {
mResult=  mDatabaseRepository.fetchData(getApplication().
            getContentResolver());
    }
}

我的数据库存储库

  public class DatabaseQueryRepository {
private static final int TOKEN_QUERY=0;
private QueryHandler mQueryHandler;
private String[] datacolumns;
private String sortorder;
@NonNull
public static DatabaseQueryRepository newInstance(){
    return new DatabaseQueryRepository();
}

public MutableLiveData<Cursor> fetchData(ContentResolver contentResolver){
mQueryHandler = new QueryHandler(contentResolver);
    datacolumns = new String[]{
            MediaStore.Audio.Playlists.DATA,
            MediaStore.Audio.Playlists.NAME,
            MediaStore.Audio.Playlists._ID};
    sortorder = MediaStore.Audio.Playlists.NAME;
    Uri uri = MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI;
    final String criteria =
            MediaStore.Audio.Playlists.NAME
                 ;


    final MutableLiveData<Cursor> result = query(TOKEN_QUERY,uri,datacolumns,criteria, null, sortorder );

return result;
}
private MutableLiveData<Cursor> query(int token,
                                      Uri uri,
                                      @Nullable String[] projection,
                                      @Nullable String selection,
                                      @Nullable String[] selectionArgs,
                                      @Nullable String orderby
){
    final MutableLiveData<Cursor> result = new MutableLiveData<>();
    mQueryHandler.startQuery(token, result, uri,projection,selection, selectionArgs, orderby );

    return result;
}

private static class QueryHandler extends AsyncQueryHandler {

    public QueryHandler(ContentResolver cr) {
        super(cr);

    }

    @Override
    protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
        //  super.onQueryComplete(token, cookie, cursor);
        MutableLiveData<String> mutabledata = (MutableLiveData<String>) cookie;

        try {
            switch (token) {
                case TOKEN_QUERY:
                    if (cursor != null && cursor.moveToFirst()) {
                        String demostring = cursor.getString(0);
                        int test = cursor.getCount();
                        String playlist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Playlists.NAME));
                        long playlist_id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Playlists._ID));

                        //    ((MutableLiveData<String>) cookie).setValue(demostring);

                    }
                    break;
            }
        } finally {
            if (cursor!=null){
            //    cursor.close();
            }
        }
    }


    @Override
    public void startQuery(int token, Object cookie, Uri uri, String[] projection, String selection, String[] selectionArgs, String orderBy) {
        super.startQuery(token, cookie, uri, projection, selection, selectionArgs, orderBy);
    }
}

在受保护的void onQueryComplete中,游标返回值。我想要的是此游标,但示例代码将其关闭。?

在我的片段中,我设置了观察者

       @Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    PlaylistViewModel viewModel =
            ViewModelProviders.of(this).get(PlaylistViewModel.class);
    viewModel.getData().observe(this, data -> {

    });

问题: -如何掌握光标。我从文档中知道应该通过ViewModel。 -是否需要将游标传递给适配器,还是可以从适配器内部访问游标? -我对存储库创建游标感到困惑,但是mutableLivedata以及如何访问它呢?

1 个答案:

答案 0 :(得分:1)

更新我原来的问题。设置观察者、变量和触发变化的调用。 onLiveDataFinished 是我自己设置适配器的方法

    private Observer<Cursor> mObserver = new Observer<Cursor>() {
    @Override
    public void onChanged(@Nullable Cursor cursor) {
        if(cursor!=null && cursor.moveToFirst()) {
            mAdapter = new PlaylistFragmentAdapter(getContext(), listener);
            onLiveDataFinished(cursor);
        }else{
            // switch off progressbar when nothing found
            mCallbacks.onPostExecute();
        }
    }
};


        mContext = getActivity();
    datacolumns = new String[]{

            MediaStore.Audio.Playlists.NAME,
            MediaStore.Audio.Playlists._ID};
    sort_order = MediaStore.Audio.Playlists.NAME;
    selection=
            MediaStore.Audio.Playlists.NAME
                          + " NOT LIKE \'%.m3u%\' AND "
                    + MediaStore.Audio.Playlists.NAME
                    + " NOT LIKE \'smb_%\'";

    selectionArgs=null;
    media_uri=uris.get_audio_playlists_uri();

       ViewModelFactory factory =
            new ViewModelFactory(
                    getActivity().getApplication(),
                    mId,
                    media_uri,
                    datacolumns,
                    selection,
                    selectionArgs,
                    sort_order);


    viewModel = ViewModelProviders.of(this, factory).get(com.flyingdutchman.newplaylistmanager.architecture_components.viewModel.class);
    viewModel.getData().observe(getViewLifecycleOwner(), mObserver);
    viewModel.setId(mId,media_uri,datacolumns,selection, selectionArgs, sort_order);