Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
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 Utils
TO THE RESCUE!
IterableCursor<T>
extends Iterable<T>, Cursor
// Public API:
public T peek();
public T nextDocument();
public T previousDo...
IterableCursor<T>
extends Iterable<T>, Cursor
// Public API:
public T peek();
// public T nextDocument();
// public T prev...
public class User {
public User(String name, String bio) { /* ... */ }
}
public class UserCursor extends IterableCursorWra...
IterableCursorWrapper<T> Helper Methods
getString(columnIndex) vs. getStringHelper(columnName, defaultValue)
getDouble(col...
IterableCursorWrapper<T> Helper Methods
getString(columnIndex) vs. getStringHelper(columnName, defaultValue)
getDouble(col...
IterableCursorWrapper<T> Helper Methods
getString(columnIndex) vs. getStringHelper(columnName, defaultValue)
getDouble(col...
Back to code
public class MyDatabase extends SQLiteOpenHelper {
// ...
public IterableCursor<User> queryAllUsers() {
Curso...
IterableCursor<User> users = myDb.queryAllUsers();
for (User user : users) {
if (user.isMyBestFriend()) giveSomeCake(user)...
IterableCursorAdapter<T>
Here's where the magic happens
IterableCursorAdapter<T>
public abstract View newView(Context context, T t, ViewGroup parent);
public abstract void bindVi...
IterableCursorAdapter<T>
public abstract View newView(Context context, T t, ViewGroup parent);
public abstract void bindVi...
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 ne...
CursorList
Great for filtering data sets:
@Override
public IterableCursor<User> runQueryOnBackgroundThread(CharSequence co...
For the RxJava Folks:
Observable<IterableCursor<Pojo>> observable = // ...
observable
.map(cursor -> new CursorList(cursor...
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?
Upcoming SlideShare
Loading in …5
×

Android Cursor Utils - NYC Android Meetup

1,097 views

Published on

An overview of Venmo's Cursor Utilities library given at the New York Android Meetup. The library simplifies turning SQLite cursors into Java Objects, using large relational data in ListViews, and iterating through SQL queries

Published in: Technology
  • Login to see the comments

Android Cursor Utils - NYC Android Meetup

  1. 1. Cursor Utils
  2. 2. CURSORS: THE GOOD PARTS
  3. 3. ▸ Fast ▸ Flexible ▸ Good for large datasets
  4. 4. CURSORS:THE ROUGH POINTS
  5. 5. ▸ No type safety ▸ Lots of code duplication ▸ No easy iteration mechanism
  6. 6. Cursor Utils TO THE RESCUE!
  7. 7. IterableCursor<T> extends Iterable<T>, Cursor // Public API: public T peek(); public T nextDocument(); public T previousDocument(); public Iterator<T> iterator();
  8. 8. 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.
  9. 9. 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); } }
  10. 10. IterableCursorWrapper<T> Helper Methods getString(columnIndex) vs. getStringHelper(columnName, defaultValue) getDouble(columnIndex) vs. getDoubleHelper(columnName, defaultValue) // ... get*(columnIndex) vs. get*Helper(columnName, defaultValue)
  11. 11. 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.
  12. 12. 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.
  13. 13. Back to code public class MyDatabase extends SQLiteOpenHelper { // ... public IterableCursor<User> queryAllUsers() { Cursor cursor = getReadableDatabase().query(TABLE_USERS, /* ... */); return new UserCursor(cursor); } }
  14. 14. IterableCursor<User> users = myDb.queryAllUsers(); for (User user : users) { if (user.isMyBestFriend()) giveSomeCake(user); } users.close();
  15. 15. IterableCursorAdapter<T> Here's where the magic happens
  16. 16. IterableCursorAdapter<T> public abstract View newView(Context context, T t, ViewGroup parent); public abstract void bindView(View view, Context context, T t);
  17. 17. 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
  18. 18. CursorListIterableCursor<T> + List<T>
  19. 19. CursorListIterableCursor<T> + List<T> (Cursor + Iterable<T>) + List<T>
  20. 20. CursorList Useful if you want to only have one instance created per row. (IterableCursorWrapper<T> by default creates a new instance on every .peek())
  21. 21. CursorList Great for filtering data sets: @Override public IterableCursor<User> runQueryOnBackgroundThread(CharSequence constraint) { CursorList<User> filtered = new CursorList<User>(); for (User user : getCursor()) { if (user.nameMatches(constraint)) { filtered.add(user); } } return filtered; }
  22. 22. For the RxJava Folks: Observable<IterableCursor<Pojo>> observable = // ... observable .map(cursor -> new CursorList(cursor)) .subscribeOn(Schedulers.io) .observeOn(AndroidSchedulers.mainThread())
  23. 23. For the RxJava Folks: Observable<IterableCursor<Pojo>> pojos = // ... Observable.from(pojos) .forEach(pojo -> /* ... */);
  24. 24. Ron Shapiro ron@venmo.com @rdshapiro ! venmo.com/ronshapiro Questions?
  25. 25. github.com/venmo/cursor-utils compile ‘com.venmo.cursor:library:0.2’ ! Contribute! Where can I get the new hotness?

×