@blog.justoneplanet.info

日々勉強

AsyncQueryHandlerを使ってSQLiteのクエリを非同期処理する

特に重いクエリは使ってないんだが、とりあえず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);
    }
}

コメントはまだありません»

No comments yet.

RSS feed for comments on this post.TrackBack URL

Leave a comment