使用光标加载器的RecyclerView在频繁更新时太慢

时间:2016-01-27 12:56:52

标签: java android android-recyclerview recycler-adapter

我从数据库中获取podcast供稿并使用 LoaderManager.LoaderCallbacks 在RecyclerView中显示它。在我的内容提供商中:

  1. 我在内容解析器查询()方法中注册了一个“观察者”:cursor.setNotificationUri(getContext().getContentResolver(), uri);
  2. 当我在内容解析器中更新/插入/删除时,我会通过:getContext().getContentResolver().notifyChange(uri, null);通知观察者,以便在需要时触发onLoaderReset()
  3. 然后我有 DownloadManager 的服务,每秒都会更新我持续下载到数据库的进度。加载程序不断加载来自数据库的数据,我可以看到UI中每个下载剧集的变化进度。

    我认为,这是一种通知变更的错误方法,而且速度非常慢,但我现在想不出更好的解决方案。您能否建议使用RecyclerView和下载进度的任何有效解决方案?

    我使用RecyclerView的自定义活动

    public class MyActivity
        implements LoaderManager.LoaderCallbacks<Cursor> {
    
        private RecyclerView mRecyclerView;
        private MyCustomRecyclerViewAdapter mAdapter;
    
        ...
    
        @Override
        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
            return new CursorLoader(this,
                myDataUri, null, null, null, null
            );  
        }   
    
        @Override
        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
            mAdapter.swapCursor(data);
        }
    
        @Override
        public void onLoaderReset(Loader<Cursor> loader) {
            mAdapter.swapCursor(null);
        }
    
        ...
    }
    

    我的自定义适配器

    public class MyCustomRecyclerViewAdapter
        extends RecyclerView.Adapter<EpisodeAdapter.AudioAdapterViewHolder> {
    
        ...
    
        public void swapCursor(Cursor newCursor) {
            mCursor = newCursor;
            notifyDataSetChanged();
        }
    
        ... 
    }
    

2 个答案:

答案 0 :(得分:2)

当适配器具有稳定的ID时,

ReclyclerView更有效(特别是notifyDataSetChanged()方法)。

如果您的数据有ID(例如来自数据库),您应该考虑使用setHasStableIds(true)并正确覆盖getItemId(int position)

我不确定这会完全解决你的问题,但这绝对是一个很好的做法。

答案 1 :(得分:0)

不要使用<div class="row"> <div class="form-inline col-sm-6" style="overflow-x: hidden"> <div class="row"> <div class="col-sm-6"> <label class="control-label">{{ 'commonLabelName' | translate }}:</label> </div> <div class="col-sm-6"> <div class="btn-group" ng-class="{ 'has-error': newEventForm.name.$invalid && newEventForm.name.$dirty }"> <input required ng-maxlength="100" name="name" class="form-control" ng-model="vm.newEvent.name" /> </div> </div> </div> </div> <div class="form-inline col-sm-6"> <div class="row"> <div class="col-sm-6"> <label class="control-label">{{ 'commonLabelAction' | translate }}:</label> </div> <div class="col-sm-6"> <div class="btn-group" style="width: 70%" ng-class="{ 'has-error': newEventForm.action.$invalid && newEventForm.action.$dirty }"> <select name="action" required class="form-control" style="width: 100%" ng-model="vm.newEvent.actionId" ng-options="action.id as action.name for action in vm.actionList"></select> </div> </div> </div> </div> ,而是使用notifyDataSetChanged()notifyItemInserted()来获得性能提升。

对于已解决的类似问题,请查看at this