6

Android プログラミングの入門書を読んだ後、実際にはカバーされていないいくつかのトピックの理解を深めるために、サンプル アプリケーションを変更したいと考えました。変更を行う際にエラーが発生しましたが、エラーが機能する場合と機能しない場合がある理由が知りたいです。

アプリケーション内のアクティビティは、一連の質問を に格納しますHashtable<Integer, Question>。ここで、Question は、int と 2 つの String を保持する小さなクラスです。最初に書かれたように、アクティビティはすべてのサーバーから質問をダウンロードするため、重複したダウンロードを防ぐため onCreate()に実装したいと考えました。を使用してハッシュテーブルをバンドルに保存します。onSaveInstanceState()onSaveInstanceState()putSerializable()

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
            // mQuestions is a member variable of 
            // type Hashtable<Integer, Question>
    if (mQuestions != null && mQuestions.size() > 0) {
        outState.putSerializable(SAVED_QUESTIONS, mQuestions);
    }
}

Parcelable とは何か、またはその実装方法を知る前でさえ、画面の向きの変更に対して完全に機能しました。エミュレーターのホーム キーを押したときに問題が発生したことだけがわかりました。アプリは静かにクラッシュし、LogCat の出力はありませんでした。スタック トレースにより、Parcelable を検索し、Question に実装させました。

私の質問は、私が間違ったことではありません。問題は次のとおりです。Question クラスが Parcelable を実装していない場合、アプリがホームを押したときにのみクラッシュし、画面の向きが変わったときではないのはなぜですか?

4

3 に答える 3

2

私が理解している限り、構成の変更後にアクティビティを再作成するときに、Android はインスタンスの状態をシリアル化しません。それがあなたのコードが機能する理由です。永続化されたオブジェクトは、メモリ内にのみ存在するため、パーセル可能である必要はありません。

これは最適化のように見えます。この場合、Android はプロセスが終了しないことを認識しており、インスタンスの状態をファイルに保存する必要はありません。(理論的には、プロセスは構成の変更中に終了する可能性があり、Android がこの問題をどのように解決するかはよくわかりません)。

ただし、ユーザーが Home キーを押すと、アプリはバックグラウンドになります。また、メモリが不足している場合は、そのプロセスを終了できます。Android は、将来アプリとそのアクティビティを復元できるように、アクティビティの状態をファイルに保存する必要があります。この場合、インスタンスの状態は実際にシリアル化され、永続的なストレージに保存されます。それがあなたのコードが機能しない理由です。

プロセスの終了はいつでも発生する可能性があるため、実装の詳細に依存することはできません。インスタンスの状態をパーセル可能またはシリアライズ可能にするだけで、この問題に再び直面することはありません。

于 2011-07-12T20:52:02.750 に答える
1

スティーブ・モーズリーの引用

http://developer.android.com/reference/android/app/Activity.htmlのアクティビティ状態に関するドキュメントによると、とを使用するのは安全ではないことに注意してください。onSaveInstanceStateonRestoreInstanceState

ドキュメントには次のように記載されています(「アクティビティライフサイクル」セクション)。

後者はライフサイクルコールバックの一部ではないため、onPause()代わりに永続データを保存することが重要であることに注意してください。そのため、ドキュメントで説明されているように、すべての状況で呼び出されるわけではありません。onSaveInstanceState(Bundle)

つまり、保存/復元コードonPause()onResume()代わりに入れてください!

于 2011-07-11T10:42:25.900 に答える
0

アプリはクラッシュしませんでした。ユーザーがホームキーをクリックすると、単にシャットダウンされました。そのため、LogCatへの出力はありませんでした。

これを確認するには、Activity.onDestroy()にブレークポイントを設定します。私が正しければ、onDestroy()は呼び出されますが、onSaveInstanceState()は呼び出されません。これは、onSaveInstanceState()が呼び出されるのは、アプリがシャットダウンされたときではなく、バックグラウンド状態にあるときだけだからです。

シャットダウン時にアプリの状態を保存する必要がある場合は、コードをonDestroy()に配置し、バンドルよりも永続的なものに保存します。

バリー

于 2011-07-13T22:48:57.350 に答える