POJO's versus Cursors in Android
문제
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 of my ListViews. Right now this adapter accepts a Collection of Articles, which I normally get from my wrapper around an SQLiteDatabase.
The signature of the AlphabetIndexer constructer is as follows:
public AlphabetIndexer (Cursor cursor, int sortedColumnIndex, CharSequence alphabet)
Since this doesn't accept a Collection or something similar, just a Cursor, it got me wondering: maybe I shouldn't be creating objects for my model, and just use the Cursors returned from the database?
So the question is, I guess: what should I do, represent data with Collections of POJO's, or just work with Cursors throughout my app?
Any input?
해결책
I have run into similar issues. Right now, I am tending away from POJOs. Note, though, that you can create your own Cursor
interface for a collection of POJOs, if you so choose.
다른 팁
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();
}
}
여기를 두 가지 고려해야합니다 :
-
jQuery inarray 함수는 기본 배열 IndexOF 함수를 호출하여 구현됩니다. 그렇지 않으면 루프를 사용하여 일치하는 검색시 배열 요소를 순환합니다.
-
현재 inarray 호출이 이미 실현되면 FieldSinView는 내부적으로 필드의 배열 일뿐 만 아니라 배열의 일부가 아닌 객체 인 SPFieldCollection입니다. Public API ($ 기호로 시작하는 모든 변수는 JavaScript가 되더라도, 아무 것도 액세스하는 것을 멈추게하지만 미래의 업그레이드가 당신을 멈추지 않을 수있는 것은 아닙니다. 코드를 선택한 경우 코드를 선택하십시오.
성능 - 현명하며, GetEnumerator 기능 (필드 내부 이름)의 배열을 빌드하기 위해 GetEnumerator 기능에서 얻은 열거 자로 FieldSinView 모음을 통해 먼저 루프를 돌보지 않을 것입니다. 그런 다음이 새로 만들어진 배열을 inArraRay 함수 호출에 두 번째 인수로 사용합니다. 성능이 히트 히트가 눈에 띄지 않을 것이라고 생각합니다 (당신이 당신의 견해에 가지고있는 분야가 얼마나 많은 분야).
그렇지 않으면 "> Lodash Library _some 함수를 사용하여 배열을 열거하고 각 항목을 전달할 수 있습니다. 콜백 함수 (검색 일치 조건)는 전달 값을 찾고 전체 컬렉션을 반복하지 않으면 반환됩니다.
Answers are 4 years old. I think now we have enought CPU power to get away with more stuff. My idea would be to work only with POJOs and ArrayLists; and extending CursorLoader to map cursor to POJOs in the background and deliver arraylist to activity;
unless youre queries hundreds of rows but then, how often are you doing that vs. niceness of using POJOs, getters and setters