J'aime créer des classes POJO adossées à un curseur. Une classe POJO adossée à un curseur possède un constructeur qui prend un curseur et offre les avantages suivants :
- Des récupérateurs faciles à utiliser qui renvoient le bon type de contenu, ce qui est bien mieux que d'obtenir des index et de devoir se souvenir du type de données dans la base de données
- Des méthodes gâchettes qui calculent leurs résultats à partir d'autres gâchettes, comme le veut la programmation OO.
- Les valeurs de retour des getter peuvent être des enums !
Ces quelques avantages valent bien un peu de code passe-partout, de nombreux bogues ont été évités maintenant que les ingénieurs utilisateurs n'accèdent pas eux-mêmes aux colonnes du curseur. Nous utilisons toujours la classe CursorAdapter, mais la première ligne de la méthode bindView consiste à créer le POJO soutenu par le curseur à partir du curseur et à partir de là, le code est magnifique.
Ci-dessous un exemple d'implémentation, c'est un jeu d'enfant pour les ingénieurs utilisateurs de transformer un curseur opaque en un objet User clairement défini, à partir duquel il peut être transmis et accédé comme un POJO normal tant que le curseur n'est pas fermé. Le SmartUserCursor est une classe spéciale que j'ai écrite pour m'assurer que la position du curseur est mémorisée et restaurée avant l'accès au curseur. Elle stocke également les index des colonnes du curseur afin que les recherches soient rapides.
EXEMPLE :
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();
}
}