Android Cursor Utils - NYC Android Meetup

Post on 20-Jun-2015

409 views 0 download

Tags:

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

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?