2011-09-19 14 views
8

私は最初のAndroidアプリを開発中です。このモデルには、ユーザーが更新を行ったときにデータベースに保持されるモデルがあります。onSaveInstanceState/onPause - プロセスが終了する前に状態が完全に保存されるまで待つ

onSaveInsanceStateが呼び出されたとき、ユーザーがデータベースから作業していたドキュメントをロードするために使用できるIDを保存します。しかし、これは、文書が完全にデータベースにヒットした後にのみ発生する可能性があります。いくつかのケースでは、複雑な文書を永続化するのに数秒かかることがあります(私はすべての冗長なログアウトを取るとスピードアップすることを望んでいます。実際には複雑な文書が段階的に構築されます)。データベースに永続化されるため、複雑な文書をすべて一度に保存する必要はありません)。

Androidでのスレッドの#1ルールは「UIスレッドをブロックしない」ため、DBのやりとりは別のスレッドで行われます。しかし、Androidライフサイクルの理解は、多くの場合、Androidシステムがプロセスを強制終了したいので、onSaveInstanceStateが呼び出されているということです。これは、DBスレッドが文書の保存を完了するまでこのメソッドを返すことができないことを示唆しています(実際には私の現在の設計では、DBに保存されるまで文書のID番号は実際にはわかりませんが、私は保存された状態の束にそれを置くこともできません)。

永続化タスクが完了するのを待っているUIスレッドをブロックすることは適切ですか?プロセスが強制終了されたためにonSaveInstanceStateが呼び出されると、アプリケーションはフォアグラウンドで表示されなくなるため、応答しなくなるインターフェイスはありません。

ただし、onSaveInstanceStateは、画面の向きが変更されたときに発生する設定の更新によってアクティビティインスタンスがゴミ箱に移動しているときにも呼び出されます。画面を横向きに回転させて数秒間何もしないと、非常に残念です。この場合、プロセス(とメモリ空間)はまだ残っていますので、IDの代わりにBundleへの参照を保存するだけでドキュメントがデータベースに確実にアクセスするようにする必要はありません。しかし、私はこれらの2つのケースの違いを伝える方法を知らない。

このような状況では、慣例がありますか?スレッドを安全にブロックするだけでいいですか?ブロックして待機するために通常のJavaスレッドプリミティブを使用できますか?何かできることはありますかはスレッドをブロックしませんが、Androidがプロセスを終了する前に永続タスクが完了するようにしますか?

の場合は、onSaveInstanceStateが必ずしも呼び出されるとは限りません。

答えて

0

あなたはあなたのUIをブロックしますが、空白の画面を表示しないで、必要なxml要素をロードし、非同期タスクから呼び出し、データベース内のドキュメントを保存します。

は、このリンクをクリックしてください:あなたはonSaveInstanceStateに永続的な節約に行う必要はありませんAyncTask Exmaple

+0

私は、AsyncTaskのポイントはUIスレッドをブロックしないと思っていましたか?長持ちする操作をするためにそれを使用することの全体的なポイントではありませんか? – Ben

+0

Configの変更に問題がある場合は心配しないでください。このアクティビティタグのmainfestファイルにあるconfigChangesを書き留めておけば、オリエンテーションが変更されたときにonSaveInstanceState()を呼び出すことはありません。それは活動を再開させることはない –

+0

それは便利です(しかし、それ自身の問題を抱えています)。しかし、問題が完全に無関係です。これは、保存がバックグラウンドによって行われた場合にアプリケーションが終了したときに、糸。 – Ben

2

インスタンスが迅速onRestoreInstanceStateで再開できるように、あなたはかなりちょうどBundleにインスタンス状態を保存することができます。

ドキュメントでは、ユーザー編集などの重要な永続データをに保存する必要があると書かれていますが、次のアクティビティでは何をしてもよいように高速にする必要があります。

ここで私のお勧めは、onSaveInstanceStateに文書のテキストとそれ以外のものを保存してonRestoreInstanceStateに復元することです。 を使用して "バックアップコピー"をどこか速く保存してください(一時ファイルかもしれません)。onResumeに復元することができます(データベースに保存されていない場合)。実際にデータをデータベースに保存するには、onStop(アクティビティがバックグラウンドのときに呼び出されます)を使用します。

が呼び出された後でアクティビティが終了する可能性があることに注意してください(システムに残されたリソースが非常に少ない場合を除き...)。そのため、データベースにコミットしようとする前にクイックバックアップを保存します。

編集 - エクストラアプリケーションがシステムによって殺される前に、保存処理をやっているバックグラウンドスレッドが節約行われていることを確認するには、コメント

に基づいて、と思うそれがブロックして待つように罰金です節約スレッドがから戻る前に完了するようにしますが、オリエンテーションが変更されたときにアクティビティの再起動を防止するためにandroid:configChanges="orientation"を使用することをお勧めします(また、呼び出し)。

+0

私は実際に書かれてすぐにすべてをデータベースにコミットします。私は 'onSaveInstanceState'でそれをしません。問題は、onSaveInstanceStateが呼び出されたときに最後にトリガされた保存操作*がまだ進行中である可能性があることです。永続的なデータが実際に安全になるまで、Androidシステムに「今すぐ私を殺すのは大丈夫です」と伝えるのを待つ方法を知る必要があります。とにかく私のプロセスを任意に殺すようなシステムではシステムのリソースがあまりにも少ない場合は、無修正の編集を失うのは大丈夫ですが、通常の動作条件でDB操作の途中でプロセスを終了させたくありません。 – Ben

+0

この場合、mak_just4anythingが提案するマニフェストファイルで、android:configChanges = "orientation"を使って 'onSaveInstanceState'をスキップすることができます。保存が 'onPause' /' onStop'で行われていることを確認してください。詳細はこちら:http://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange – Zharf

+0

私は明らかに私の質問を理解させていません。私の 'onPause'が' tellBackgroundThreadToSaveStateToDb'を呼び出します。良い。完了しました。今、Androidが自分のプロセスを終了させたいときにバックグラウンドスレッドが依頼を処理していないことを確認するにはどうすればよいですか? – Ben

関連する問題