Android ListView:如何避免bindView()中的数据库查询?需要获取一对多的关系数据

Posted

技术标签:

【中文标题】Android ListView:如何避免bindView()中的数据库查询?需要获取一对多的关系数据【英文标题】:Android ListView: how to avoid database query in bindView()? Need to fetch one to many relationship data 【发布时间】:2014-02-04 08:48:44 【问题描述】:

我有一个列表视图来显示专辑。在每个相册列表项中,我需要显示此相册中每张照片的一些信息。这是我的光标加载器的样子:

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) 
    return new CursorLoader(this, AlbumsColumns.CONTENT_URI, null, null, null, null);


@Override
public void bindView(View view, Context context, Cursor cursor) 

    long albumId = cursor.getLong(cursor.getColumnIndex(AlbumsColumns._ID));

    Cursor photoCursor = getContentResolver().query(PhotosColumns.CONTENT_URI, null, PhotosColumns.ALBUM_ID + " = ?", 
            new String[]Long.toString(albumId), null);

    if (photoCursor.moveToFirst())
        do

            // Here I collect the information from each photo in the album

        while(photoCursor.moveToNext());
    

    photoCursor.close();

基本上,我让游标加载器管理相册查询,每次在 bindView 中,我都会从传入的相册游标中查询照片。我觉得这可能是一个性能问题。有更好的方法吗?

【问题讨论】:

一种解决方案是使用自定义加载器,在后台线程中执行所有这些查询并返回包含您需要的信息的对象列表。 @dymmeh 是的,我刚刚意识到这应该是正确的方法。 顺便说一句,性能是一回事。有一个潜在的错误,如果我在 bingView() 中自己查询,将不会通知所有照片更新 【参考方案1】:

刚刚有了一个想法:在列表项中使用另一个游标加载器。所以这就像两级游标加载器。我稍后会发布我的结果。

编辑

提议的想法应该是处理问题的正确方法。所以我的代码是这样重构的:

// In the list view activity:

    @Override
    public void bindView(View view, Context context, Cursor cursor) 

        AlbumListItem albumListItem = (AlbumListItem)view;

        albumListItem.prepareView(getLoaderManager(), cursor);
    

// AlbumListItem is a class that has a cursor loader to query photos:
public class AlbumListItem extends RelativeLayout implements LoaderManager.LoaderCallbacks<Cursor>


public void prepareView(LoaderManager loaderManager, Cursor albumCursor)

    albumId = albumCursor.getLong(albumCursor.getColumnIndex(AlbumsColumns._ID));
    // Other init stuff

    loaderManager.initLoader(UNIQUE_LOADER_ID, null, this);


@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) 

    // Here is the async query part.

    return new CursorLoader(context, PhotosColumns.CONTENT_URI, null, PhotosColumns.ALBUM_ID + " = ?", new String[]Long.toString(albumId), null);



【讨论】:

以上是关于Android ListView:如何避免bindView()中的数据库查询?需要获取一对多的关系数据的主要内容,如果未能解决你的问题,请参考以下文章

Android ListView:如何避免bindView()中的数据库查询?需要获取一对多的关系数据

避免将重复项添加到 listview android

如何使用“自动调整大小”避免 Android 中的小部件重叠。

Android 设置ListView不可点击(避免闪退)

android ListView显示多个类型item 和 item中控件抢夺焦点解决办法

android ListView显示多个类型item 和 item中控件抢夺焦点解决办法