特に重いクエリは使ってないんだが、とりあえずAsyncQueryHandlerを使ってSQLiteのクエリを非同期で処理する。
■実装
以下のようにmanifestファイルのapplication要素内にproviderを追加する。
<provider android:name=".Provider" android:authorities="info.justoneplanet.android.sample.provider"<!--アクセスするためのURI--> android:exported="false"/><!--非公開にしないと他のアプリからアクセスできてしまう-->
セキュリティには注意する。
Helper.java
class Helper extends SQLiteOpenHelper { private static final int VERSION = 1; private static final String FILENAME = "info.justoneplanet.android.sample.db"; static final String TABLENAME = "tbl"; static final String ID = "_id"; static final String CREATED = "created"; static final String NAME = "name"; static Helper INSTANCE = null; private Helper(Context context, CursorFactory factory) { super(context, FILENAME, factory, VERSION); } public static Helper getInstance(Context context, CursorFactory factory) { if (INSTANCE == null) { INSTANCE = new Helper(context, factory); } return INSTANCE; } @Override public void onCreate(SQLiteDatabase db) { db.execSQL( "CREATE TABLE `" + TABLENAME + "`(" + " `" + ID + "` INTEGER PRIMARY KEY AUTOINCREMENT," + " `" + CREATED + "` INTEGER," + " `" + NAME + "` TEXT" + ");" ); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
Provider.java
以下のようにContentProviderクラスを継承したProviderクラスを作る。
public class Provider extends ContentProvider { @Override public String getType(Uri uri) { return null; } @Override public boolean onCreate() { return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Helper helper = Helper.getInstance(getContext(), null); SQLiteDatabase sdb = helper.getReadableDatabase(); Cursor cursor = sdb.query( Helper.TABLENAME, new String[]{Helper.ID, Helper.NAME, Helper.CREATED}, selection, selectionArgs, null, null, sortOrder, null ); return cursor; } @Override public Uri insert(Uri uri, ContentValues values) { Helper helper = Helper.getInstance(getContext(), null); SQLiteDatabase sdb = helper.getWritableDatabase(); sdb.insert(Helper.TABLENAME, null, values); getContext().getContentResolver().notifyChange(uri, null); return null; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { Helper helper = Helper.getInstance(getContext(), null); SQLiteDatabase sdb = helper.getWritableDatabase(); int rows = sdb.update(Helper.TABLENAME, values, selection, selectionArgs); getContext().getContentResolver().notifyChange(uri, null); return rows; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { Helper helper = Helper.getInstance(getContext(), null); SQLiteDatabase sdb = helper.getWritableDatabase(); int rows = sdb.delete(Helper.TABLENAME, selection, selectionArgs); getContext().getContentResolver().notifyChange(uri, null); return rows; } }
Table.java
public class Table { private static final Uri URI = Uri.parse("content://info.justoneplanet.android.sample.provider/"); private Context mContext; public Table(Context context) { mContext = context; } /** * データを取得する * @return ListActivity用のadapter */ public void load(final LoadObserver observer) { AsyncQueryHandler handler = new AsyncQueryHandler(mContext.getContentResolver()) { @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { super.onQueryComplete(token, cookie, cursor); observer.onLoadCursor(cursor); } }; handler.startQuery(0, null, URI, null, null, null, Helper.CREATED + " DESC"); } /** * 保存する * @return */ public void add(String name) { ContentValues contentValues = new ContentValues(); contentValues.put(Helper.NAME, name); contentValues.put(Helper.CREATED, new Date().getTime()); AsyncQueryHandler handler = new AsyncQueryHandler(mContext.getContentResolver()) { @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { super.onQueryComplete(token, cookie, cursor); } }; handler.startInsert(0, null, URI, contentValues); } /** * 一定時間経過したものを削除する * @param created * @return */ public void delete(long created) { AsyncQueryHandler handler = new AsyncQueryHandler(mContext.getContentResolver()) { }; handler.startDelete(0, null, URI, Helper.CREATED + " < ?", new String[]{String.valueOf(created)}); } /** * helper経由でdbをcloseする */ public void close() { Helper.getInstance(mContext, null).close(); } public interface LoadObserver { public void onLoadCursor(Cursor cursor); } }