android cursor utils - nyc android meetup
Post on 20-Jun-2015
406 Views
Preview:
DESCRIPTION
TRANSCRIPT
Cursor Utils
CURSORS:THE GOOD PARTS
▸ Fast▸ Flexible
▸ Good for large datasets
CURSORS:THE ROUGH POINTS
▸ No type safety▸ Lots of code duplication▸ No easy iteration mechanism
Cursor UtilsTO THE RESCUE!
IterableCursor<T>extends Iterable<T>, Cursor
// Public API:
public T peek();public T nextDocument();public T previousDocument();public Iterator<T> iterator();
IterableCursor<T>extends Iterable<T>, Cursor
// Public API:
public T peek();// public T nextDocument();// public T previousDocument(); // @see CursorUtils.java helpers// public Iterator<T> iterator();
That's it.
public class User { public User(String name, String bio) { /* ... */ }}
public class UserCursor extends IterableCursorWrapper<User> {
public UserCursor(Cursor c) { super(c); }
public User peek() { String name = getStringHelper(COLUMN_USER_NAME, "Default Name"); String bio = getLongHelper(COLUMN_USER_BIO, "No bio yet"); return new User(name, bio); }
}
IterableCursorWrapper<T> Helper Methods
getString(columnIndex) vs. getStringHelper(columnName, defaultValue)getDouble(columnIndex) vs. getDoubleHelper(columnName, defaultValue)// ...get*(columnIndex) vs. get*Helper(columnName, defaultValue)
IterableCursorWrapper<T> Helper Methods
getString(columnIndex) vs. getStringHelper(columnName, defaultValue)getDouble(columnIndex) vs. getDoubleHelper(columnName, defaultValue)// ...get*(columnIndex) vs. get*Helper(columnName, defaultValue)
Effective Java, Item 79: Use these helper methods judiciously.
IterableCursorWrapper<T> Helper Methods
getString(columnIndex) vs. getStringHelper(columnName, defaultValue)getDouble(columnIndex) vs. getDoubleHelper(columnName, defaultValue)// ...get*(columnIndex) vs. get*Helper(columnName, defaultValue)
Effective Java, Item 79: Use these helper methods judiciously.They're convenient, but definitely slower.
Back to code
public class MyDatabase extends SQLiteOpenHelper {
// ...
public IterableCursor<User> queryAllUsers() { Cursor cursor = getReadableDatabase().query(TABLE_USERS, /* ... */); return new UserCursor(cursor); }
}
IterableCursor<User> users = myDb.queryAllUsers();for (User user : users) { if (user.isMyBestFriend()) giveSomeCake(user);}users.close();
IterableCursorAdapter<T>Here's where the magic happens
IterableCursorAdapter<T>
public abstract View newView(Context context, T t, ViewGroup parent);public abstract void bindView(View view, Context context, T t);
IterableCursorAdapter<T>
public abstract View newView(Context context, T t, ViewGroup parent);public abstract void bindView(View view, Context context, T t);
"It's like ArrayAdapter<T> + CursorAdapter!"
— Our Intern
CursorListIterableCursor<T> + List<T>
CursorListIterableCursor<T> + List<T>(Cursor + Iterable<T>) + List<T>
CursorList
Useful if you want to only have one instance created per row.
(IterableCursorWrapper<T> by default creates a new instance on every .peek())
CursorList
Great for filtering data sets:
@Overridepublic IterableCursor<User> runQueryOnBackgroundThread(CharSequence constraint) { CursorList<User> filtered = new CursorList<User>(); for (User user : getCursor()) { if (user.nameMatches(constraint)) { filtered.add(user); } } return filtered;}
For the RxJava Folks:
Observable<IterableCursor<Pojo>> observable = // ...observable .map(cursor -> new CursorList(cursor)) .subscribeOn(Schedulers.io) .observeOn(AndroidSchedulers.mainThread())
For the RxJava Folks:
Observable<IterableCursor<Pojo>> pojos = // ... Observable.from(pojos) .forEach(pojo -> /* ... */);
Ron Shapiro ron@venmo.com
@rdshapiro !
venmo.com/ronshapiro
Questions?
github.com/venmo/cursor-utils compile ‘com.venmo.cursor:library:0.2’
!
Contribute!
Where can I get the new hotness?
top related