Android Cursor Utils - NYC Android Meetup

25
Cursor Utils

description

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

Transcript of Android Cursor Utils - NYC Android Meetup

Page 1: Android Cursor Utils - NYC Android Meetup

Cursor Utils

Page 2: Android Cursor Utils - NYC Android Meetup

CURSORS:THE GOOD PARTS

Page 3: Android Cursor Utils - NYC Android Meetup

▸ Fast▸ Flexible

▸ Good for large datasets

Page 4: Android Cursor Utils - NYC Android Meetup

CURSORS:THE ROUGH POINTS

Page 5: Android Cursor Utils - NYC Android Meetup

▸ No type safety▸ Lots of code duplication▸ No easy iteration mechanism

Page 6: Android Cursor Utils - NYC Android Meetup

Cursor UtilsTO THE RESCUE!

Page 7: Android Cursor Utils - NYC Android Meetup

IterableCursor<T>extends Iterable<T>, Cursor

// Public API:

public T peek();public T nextDocument();public T previousDocument();public Iterator<T> iterator();

Page 8: Android Cursor Utils - NYC Android Meetup

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.

Page 9: Android Cursor Utils - NYC Android Meetup

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

}

Page 10: Android Cursor Utils - NYC Android Meetup

IterableCursorWrapper<T> Helper Methods

getString(columnIndex) vs. getStringHelper(columnName, defaultValue)getDouble(columnIndex) vs. getDoubleHelper(columnName, defaultValue)// ...get*(columnIndex) vs. get*Helper(columnName, defaultValue)

Page 11: Android Cursor Utils - NYC Android Meetup

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.

Page 12: Android Cursor Utils - NYC Android Meetup

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.

Page 13: Android Cursor Utils - NYC Android Meetup

Back to code

public class MyDatabase extends SQLiteOpenHelper {

// ...

public IterableCursor<User> queryAllUsers() { Cursor cursor = getReadableDatabase().query(TABLE_USERS, /* ... */); return new UserCursor(cursor); }

}

Page 14: Android Cursor Utils - NYC Android Meetup

IterableCursor<User> users = myDb.queryAllUsers();for (User user : users) { if (user.isMyBestFriend()) giveSomeCake(user);}users.close();

Page 15: Android Cursor Utils - NYC Android Meetup

IterableCursorAdapter<T>Here's where the magic happens

Page 16: Android Cursor Utils - NYC Android Meetup

IterableCursorAdapter<T>

public abstract View newView(Context context, T t, ViewGroup parent);public abstract void bindView(View view, Context context, T t);

Page 17: Android Cursor Utils - NYC Android Meetup

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

Page 18: Android Cursor Utils - NYC Android Meetup

CursorListIterableCursor<T> + List<T>

Page 19: Android Cursor Utils - NYC Android Meetup

CursorListIterableCursor<T> + List<T>(Cursor + Iterable<T>) + List<T>

Page 20: Android Cursor Utils - NYC Android Meetup

CursorList

Useful if you want to only have one instance created per row.

(IterableCursorWrapper<T> by default creates a new instance on every .peek())

Page 21: Android Cursor Utils - NYC Android Meetup

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

Page 22: Android Cursor Utils - NYC Android Meetup

For the RxJava Folks:

Observable<IterableCursor<Pojo>> observable = // ...observable .map(cursor -> new CursorList(cursor)) .subscribeOn(Schedulers.io) .observeOn(AndroidSchedulers.mainThread())

Page 23: Android Cursor Utils - NYC Android Meetup

For the RxJava Folks:

Observable<IterableCursor<Pojo>> pojos = // ... Observable.from(pojos) .forEach(pojo -> /* ... */);

Page 24: Android Cursor Utils - NYC Android Meetup

Ron Shapiro [email protected]

@rdshapiro !

venmo.com/ronshapiro

Questions?

Page 25: Android Cursor Utils - NYC Android Meetup

github.com/venmo/cursor-utils compile ‘com.venmo.cursor:library:0.2’

!

Contribute!

Where can I get the new hotness?