我喜欢创建游标支持的 POJO 类。Cursor 支持的 POJO 类有一个构造函数,它接受一个 Cursor 并提供以下好处:
- 易于使用的 getter 可以返回正确的内容类型,比获取索引和必须记住数据库中的数据类型要好得多
- 从其他 getter 计算结果的 getter 方法,就像 OO 编程应该如何
- Getter 返回值可以是枚举!
这几个好处非常值得一些样板代码,由于用户工程师自己不访问游标列,因此避免了许多错误。我们仍然使用 CursorAdapter 类,但是 bindView 方法的第一行是从 Cursor 创建 Cursor-backed POJO,从那时起代码就很漂亮了。
下面是一个示例实现,用户工程师可以轻松地将不透明的光标转换为明确定义的用户对象,从那时起,只要后备光标没有关闭,它就可以像常规 POJO 一样传递和访问。SmartUserCursor 是我编写的一个特殊类,用于确保在访问游标之前记住并恢复游标位置,它还存储游标列索引,因此查找速度很快。
例子:
public class User {
private final SmartUserCursor mCursor;
public User(SmartUserCursor cursor, int position) {
mCursor = new SmartUserCursor(cursor, position);
}
public long getUserId() {
return mCursor.getLong(SmartUserCursor.Columns.userId);
}
public UserType getType() {
return UserType.valueOf(mCursor.getString(SmartUserCursor.Columns.type));
}
public String getFirstName() {
return mCursor.getString(SmartUserCursor.Columns.firstName);
}
public String getLastName() {
return mCursor.getString(SmartUserCursor.Columns.lastName);
}
public final String getFullName() {
return getFirstName() + " " + getLastName();
}
public static User newUserFromAdapter(BaseAdapter adapter, int position) {
return new User((SmartUserCursor)adapter.getItem(position), position);
}
public static User newUserBlocking(Context context, long UserId) {
Cursor cursor = context.getContentResolver().query(
Users.CONTENT_URI_CLIENT,
Users.DEFAULT_USER_PROJECTION,
Users.Columns.USER_ID+"=?",
new String[] {String.valueOf(UserId)},
null
);
if (cursor == null || !cursor.moveToFirst()) {
throw new RuntimeException("No User with id " + UserId + " exists");
}
return new User(new SmartUserCursor(cursor, Users.DEFAULT_USER_PROJECTION), -1);
}
public final void closeBackingCursor() {
mCursor.close();
}
}