POJO's versus Cursors in Android

后端 未结 4 1422
甜味超标
甜味超标 2020-12-13 02:43

I usually tend to define the model layer of my apps using POJO\'s, such as Article, Comment, etc.

I was about to implement an AlphabetIndexer in the adapter of one o

4条回答
  •  时光说笑
    2020-12-13 03:23

    I like to create Cursor-backed POJO classes. A Cursor-backed POJO class has a constructor that takes a Cursor and provides the following benefits:

    • Easy to use getters that return the proper content type, much better than getting indexes and having to remember the type of data in the database
    • Getter methods that compute their results from other getters, just like how OO programming ought to be
    • Getter return values can be enums!

    These few benefits are well worth some boilerplate code, many many bugs have been averted now that user-engineers aren't accessing cursor columns themselves. We still use the CursorAdapter class, but the first line in the bindView method is to create the Cursor-backed POJO from the Cursor and from then on the code is beautiful.

    Below is an example implementation, it's a snap for user-engineers to turn an opaque cursor into clearly defined User object, from that point on it can be passed around and accessed just like a regular POJO so long as the backing cursor is not closed. The SmartUserCursor is a special class I wrote to ensure that the cursor position is remembered and restored before the cursor is accessed and it also stores the cursor column indexes so lookups are fast.

    EXAMPLE:

    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();
        }
    
    }
    

提交回复
热议问题