recyclelerView自定义适配器binditem在插入数据库时​​被调用

时间:2018-01-10 17:15:05

标签: android android-recyclerview recycler-adapter

我的应用程序显示播放列表,我在每个播放列表中都会在recyclerview中显示albumart。 自定义适配器显示行。一切正常但是当我使用asynctask添加另一个播放列表时,显示会重新绘制几次。我检查过没有adapter.notifydatasetchanged()调用。单步执行代码我发现当有resolver.insert

时会发生这种情况

在此示例中,例程为整个专辑或曲目创建新的播放列表。

        public void addTracksToPlaylist(Context context, String music_id,
                                long playlist_id, String nmode, int base) {
    // feed it the album_id or track_id
    Uri mediauri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    ContentResolver resolver = context.getContentResolver();


    Uri exturi = MediaStore.Audio.Playlists.Members.getContentUri(
            "external", playlist_id);
    String[] projection = {MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.TRACK};
    String where = MediaStore.Audio.Media.ALBUM_ID + " =?";
    String orderBy = null;
    if (nmode.equals(context.getString(R.string.track_mode))) {
        where = MediaStore.Audio.Media._ID + "=?";

    }
    orderBy = MediaStore.Audio.Media.ARTIST + " ASC, "
            + MediaStore.Audio.Media.ALBUM + " ASC , " +
            "CAST(" + (MediaStore.Audio.Media.TRACK) + " AS INTEGER) ASC";
    String[] whereVal = {music_id};

    Cursor c = resolver.query(mediauri, projection, where, whereVal,
            orderBy);

    if (c != null && c.moveToFirst()) {
        int idColumn = c.getColumnIndex(MediaStore.Audio.Media._ID);
        ContentValues values = new ContentValues();
        boolean stamp = prefs.getstampSelected(context);

        for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
            String audio_id = c.getString(idColumn);
            values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, base);
            values.put(MediaStore.Audio.Playlists.Members.AUDIO_ID, audio_id);
            try {
                resolver.insert(exturi, values);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //   String thistrack= track.getfullPathfromAudioId(context,audio_id);
            //  Log.i(TAG,"position : "+base +" Inserted track = "+ audio_id + " track "+thistrack+ " Album_id = "+ music_id);
            base++;
            if (stamp) {
                try {
                    track.updateTrackModifiedDate(audio_id, context);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        c.close();
    }
}

如何防止在后台发生的这些操作会影响播放列表的显示。或者换句话说,为什么/我的recyclerView"活跃"因为它似乎意识到数据库中的变化。

更新: 来自Android开发者网站:

Loader将监控数据的变化,并通过此处的新呼叫向您报告。您不应该自己监控数据。例如,如果数据是Cursor并将其放在CursorAdapter中,请使用CursorAdapter(android.content.Context,android.database.Cursor,int)构造函数,而不传入FLAG_AUTO_REQUERY或FLAG_REGISTER_CONTENT_OBSERVER(即使用0表示flags参数)。这可以防止CursorAdapter自己观察Cursor,这是不需要的,因为当发生更改时,你会得到一个新的Cursor,在这里抛出另一个调用。

加载程序的监视和报告显示在onLoadFinished调用中,在我的情况下重置适配器。

1 个答案:

答案 0 :(得分:0)

正如评论中所述,Loader监控基础数据的变化。解决方案最终很简单。 我宣布一个布尔变量

       private boolean processing=false;

在onPreExecute()中将变量设置为true,在AsyncTask的onPostExecute()中设置为false。

当一个更改触发OnLoadFinished调用时,我测试处理的值并跳过代码。完成后,我调用getLoaderManager()。restartLoader等