2013年7月5日金曜日

PCで作ったSQLiteのDBファイルをAndroidで使う


データベースが使いたくてSQLiteOpenHelperのonCreateでテーブルつくってデータインサートしてってやってたんだけど、さすがにめんどい。
jsonファイルをassetsに置いてonCreateでデータベースに入れ込むとかもやってみたけど、なんか遅い。
って思ってたらすごくいい記事書いてるサイトを発見。
[Android Programming] sqliteのDBファイルをPCでつくってandroidで使う

やりかた

ざっくり言うと、PCでSQLiteのDBファイル作ってassetsフォルダ突っ込む。SQLiteOpenHelperのgetWritableDatabaseのタイミングでDBをコピー。
(俺はgetReadableDatabaseでもコピーするようにした)

public class DbHelper extends SQLiteOpenHelper {
 private static final String DB_FILE_NAME = "xxx.db";
 private static final String DB_NAME = "xxx";
 private static final int DB_VERSION = 1;

 private Context context;
 private File dbPath;
    private boolean createDatabase = false;

 public DbHelper(Context context) {
  super(context, DB_NAME, null, DB_VERSION);
  this.context = context;
  this.dbPath = context.getDatabasePath(DB_NAME);
 }

    @Override
    public synchronized SQLiteDatabase getReadableDatabase() {
        SQLiteDatabase database = super.getReadableDatabase();
        if (createDatabase) {
            try {
                database = copyDatabase(database);
            } catch (IOException e) {
            }
        }
        return database;
    }

    @Override
    public synchronized SQLiteDatabase getWritableDatabase() {
        SQLiteDatabase database = super.getWritableDatabase();
        if (createDatabase) {
            try {
                database = copyDatabase(database);
            } catch (IOException e) {
            }
        }
        return database;
    }

    private SQLiteDatabase copyDatabase(SQLiteDatabase database) throws IOException {
        // dbがひらきっぱなしなので、書き換えできるように閉じる
        database.close();

        // コピー!
        InputStream input = context.getAssets().open(DB_FILE_NAME);
        OutputStream output = new FileOutputStream(this.dbPath);
        copy(input, output);
        
        createDatabase = false;
        // dbを閉じたので、また開く
        return super.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        super.onOpen(db);
        // getWritableDatabase()したときに呼ばれてくるので、
        // 初期化する必要があることを保存する
        this.createDatabase = true;
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        onUpgrade(db, oldVersion, newVersion);
    }

    // CopyUtilsからのコピペ
    private static int copy(InputStream input, OutputStream output) throws IOException {
        byte[] buffer = new byte[1024 * 4];
        int count = 0;
        int n = 0;
        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
            count += n;
        }
        return count;
    }

}

ためになる記事を書いてくれた ipreachableさん に感謝。


スポンサーリンク

Related Posts Plugin for WordPress, Blogger...