6

SQLite Asset Helperライブラリを使用して、アプリのデータベースのセットアップとアップグレードという厄介な作業を処理しています。それは非常にうまく機能しますが、残念ながら、ライブラリが次の場合にユーザーに通知する方法をまだ見つけていません。

A) データベースを初めてロードします (\assets\databases\ フォルダから解凍します)。

また

B) データベースをアップグレードします (\assets\datates にあるアップグレードされたデータベース ファイルの情報を使用)

このコードをアプリのメインのActivity.onCreate()に入れてみました。データベースが存在しない場合はメインスレッドにロードできると考え、却下できないAlertDialogでユーザーの注意をそらしました。

    File dbFile=this.getDatabasePath("gShoJMDict");
    Boolean dbExists = dbFile.exists();
    Log.i("ActivityStartScreen", String.valueOf(dbExists));

    if(!dbExists)
    {
        DialogFirstRun dialogFirstRun = new DialogFirstRun();
        dialogFirstRun.show(getSupportFragmentManager(), "dialogFirstRun");
        dialogFirstRun.setCancelable(false);
        DictHelper helper = new DictHelper(this);
        helper.getReadableDatabase();
        helper.close();
        dialogFirstRun.dismiss();
    }

残念ながら、(LogCat エントリに基づいて) SQLite Asset Helper は onCreate() のかなり前にデータベースが存在するかどうかを確認するように見えます。したがって、上記のコードのチャンクが実行されるまでに、データベースはすでに存在するため、ダイアログは表示されません。

私は ContentProvider を使用しており、query() または update() 内から getReadableDatabase() のみを呼び出していることを確認しました。私の ContentProvider の onCreate() は次のようになります...

@Override
public boolean onCreate()
{
    // Load our database
    gdb = new JMDictHelper(getContext());
    return true;
}

...しかし、移動にもかかわらずgdb = new JMDictHelper(getContext()); query() または update() の場合、SQLite Asset Helper ライブラリは、ユーザーに通知する前にデータベースをロードします。

この状況で、データベースの初期セットアップまたはアップグレードを傍受し、アプリがこれらのタスクの実行でビジーであることをユーザーに通知するにはどうすればよいですか? 現在、アプリはライブラリが終了するまで何もせずにそこに座っています。これは、期待できることを知っているのでテストには問題ありませんが、アプリを公開する準備ができたら、そのままにしておくことはできません。

4

2 に答える 2

6

あなたがまだこれについて疑問に思っているか、他の誰かがこの質問を持っている場合に備えて、私が実装した同様の問題の解決策を次に示します。getReadableDatabase() または getWritableDatabase() を呼び出すまで、SQLiteAssetHelper はデータベースをコピーしません。これらのメソッドのいずれかが MainActivity.onCreate() の前に呼び出されている場合は、ContentProvider の onCreate() メソッドで呼び出している可能性があります。ドキュメントのメソッドの説明は次のとおりです。

これを実装して、起動時にコンテンツ プロバイダーを初期化します。このメソッドは、アプリケーションの起動時に、アプリケーションのメイン スレッドで登録されているすべてのコンテンツ プロバイダに対して呼び出されます。時間のかかる操作を実行しないでください。実行すると、アプリケーションの起動が遅くなります。

重要な初期化 (データベースのオープン、アップグレード、スキャンなど) は、コンテンツ プロバイダーが (query(Uri, String[], String, String[], String)、insert(Uri, ContentValues) などを介して) 使用されるまで延期する必要があります。 . 遅延初期化により、アプリケーションの起動を高速に保ち、プロバイダが不要であることが判明した場合に不要な作業を回避し、データベース エラー (ディスクがいっぱいになるなど) によってアプリケーションの起動が停止するのを防ぎます。

SQLite を使用する場合、SQLiteOpenHelper は、データベースの管理を容易にする便利なユーティリティ クラスであり、最初に使用するまで開くのを自動的に延期します。SQLiteOpenHelper を使用する場合は、このメソッドから getReadableDatabase() または getWritableDatabase() を呼び出さないようにしてください。(代わりに、 onOpen(SQLiteDatabase) をオーバーライドして、最初に開いたときにデータベースを初期化します。)

こちら で説明されているように、ContentProvider が実際にアクセスされたときに getReadableDatabase() または getWritableDatabase() を呼び出すことができます。

ContentProvider が問題を抱えていないので、データベースが MainActivity.onCreate() に存在するかどうかを確認し、必要に応じて、ProgressDialog を表示しながらバックグラウンド スレッドにコピーできます。

// Create an AsyncTask to copy the database in a background thread while
// displaying a ProgressDialog.
private class LoadDatabaseTask extends AsyncTask<Context, Void, Void> {
    Context mContext;
    ProgressDialog mDialog;

    // Provide a constructor so we can get a Context to use to create
    // the ProgressDialog.
    LoadDatabasesTask(Context context) {
        super();
        mContext = context;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mDialog = new ProgressDialog(mContext);
        mDialog.setMessage(mContext.getString("Loading database..."));
        mDialog.show();
    }

    @Override
    protected Void doInBackground(Context... contexts) {
        // Copy database.
        new MyAssetHelper(contexts[0]).getReadableDatabase();
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        mDialog.dismiss();
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ...

    // Install databases if necessary.
    File database = getDatabasePath(DB_NAME);
    if (!database.exists()) {
        new LoadDatabaseTask(this).execute(this, null, null);
    }

    // ...
}
于 2013-08-26T22:56:28.623 に答える