3

查看 github 上的 CursorAdapter 代码(core/java/android/widget/CursorAdapter.java

getView 方法调用 mCursor.moveToPosition

public View getView(int position, View convertView, ViewGroup parent) {
    if (!mDataValid) {
        throw new IllegalStateException("this should only be called when the cursor is valid");
    }
    if (!mCursor.moveToPosition(position)) {
        throw new IllegalStateException("couldn't move cursor to position " + position);
    }
    View v;
    if (convertView == null) {
        v = newView(mContext, mCursor, parent);
    } else {
        v = convertView;
    }
    bindView(v, mContext, mCursor);
    return v;
}

当我在这里查看 CursorAdapter 代码时,会有一些情况下 fillWindow 被调用core/java/android/database/sqlite/SQLiteCursor.java

@Override
public boolean onMove(int oldPosition, int newPosition) {
    // Make sure the row at newPosition is present in the window
    if (mWindow == null || newPosition < mWindow.getStartPosition() ||
            newPosition >= (mWindow.getStartPosition() + mWindow.getNumRows())) {
        fillWindow(newPosition);
    }

    return true;
}

如果您继续查看代码,您会发现这最终会进行数据库调用。在 UI 线程上进行数据库调用的原因是什么?

4

1 回答 1

0

据我了解,光标的窗口方面旨在对调用者隐藏,因此在使用当前 API 从第一个窗口转到溢出窗口时,无法避免从主线程命中数据库。

不过,大多数查询都适合单个窗口,因此通常的做法是在 AsynTask 或 Loader 内的光标上调用 getCount(),然后再将其返回给 UI 线程,这具有加载第一个窗口的副作用。

于 2012-10-05T17:28:12.347 回答