0

ボタンをクリックすると、2 つの XML ファイルから新しい SQLite データベースを作成したいと考えています。これには LoaderManager と AsyncTaskLoader を使用するのが適切なようです。

Fragment.onCreate() 呼び出し:

setRetainInstance(true);

ボタンがクリックされると、Fragment はデータベースを作成中であることを示すフラグを設定し、レイアウトを変更して ProgressBar とキャンセル ボタンを表示し、次の呼び出しを行います。

getLoaderManager().initLoader(0, extra, this);

私のPC /エミュレーターでは、操作に12秒かかります。画面を回転すると、ローダーは Fragment の onLoaderProgressUpdate(int) (インターフェイス コールバック メソッド) を呼び出し続け、データベースの作成を完了します。しかし、onLoadFinished() メソッドを呼び出すことはありません。そこでは、レイアウトをリセットしたり、データベースが必要なボタンやアクション バー メニューを有効にしたりできます。

私は Fragment.onCreateView() でこれをやってみました:

if (mCreatDBInProgress) {
    mBTN_CreateDB.setEnabled(false);
    mDBLayout.setVisibility(View.GONE);
    mProgressBarLayout.setVisibility(View.VISIBLE);
    getLoaderManager().restartLoader(0, null, this);
}

しかし、それは私の onCreateLoader() メソッドを呼び出し、すべてをゼロから開始します。データベースを削除し、データベースの作成に使用する XML ファイルを決定するプロセスを実行するメソッドを呼び出していないため、これは問題です。XML ファイル名は、Bundle 引数でそのメソッドに渡すものです。

ProgressBar コールバック メソッドが引き続き機能する理由はわかりませんが、AsyncTaskLoader は onLoadFinished() メソッドを呼び出すことができません。LogCat は、deliverResult() を実行したことを示しています。

Bundle をメンバー変数にしようとしたので、restartLoader() 呼び出しで再利用できました。別の asyncTaskLoader を開始し、両方のスレッドが更新しようとすると、ProgressBar が行き来します。最終的に、最初のスレッドによって既に追加されたデータベースに行を追加しようとして、SQLConstraintException が発生します。

4

2 に答える 2

0

じゃ、横にしゃぶって!私は別のアイデアを思いつきました、そしてそれはうまくいきました!

restartoader()ローテーション後に呼び出す代わりに、次のように呼び出します。

getLoaderManager().initLoader(0, mExtra, this);

(何らかの理由で) AsynTaskLoader が最初のスレッドを (別のスレッドを開始する代わりに) 続行し、 onLoadFinished() 呼び出しのために Fragment に再リンクします。

そう:

initLoader() - 同じ引数で呼び出した場合、ローダーを Fragment に再接続します(int, Bundle, this)

于 2013-10-23T23:54:02.243 に答える