1

Gingerbread から ICS にアップグレードした後、Gingerbread で問題なく動作していたアプリがクラッシュし始めたことに気付きました。

アプリのメイン アクティビティ (アクティビティ A) には、データベースから入力された ListActivity (アクティビティ B) を開くメニュー オプションがあります。リスト内のエントリをクリックすると、3 番目のアクティビティ (アクティビティ C) が開きます。アクティビティ C が [戻る] ボタンで閉じられると、アクティビティ B が再表示されるはずです。

Gingerbread (および以前の Android バージョン) では、これは正常に機能し、ほとんどの場合、ICS でも引き続き正常に機能しました。ただし、アクティビティ C を長時間開いたままアプリから移動すると、クラッシュしました。アプリに戻り、アクティビティ C からアクティビティ B に戻ろうとすると、アプリが停止します。アクティビティ B の onResume で null ポインタ例外が発生したため、LogCat は「アクティビティを再開できません」と報告しました。

onResume メソッドの問題行には、アクティビティ A の onCreate メソッドで定義されている DBAdapter への参照が含まれています。アクティビティ B のさまざまなライフサイクル メソッドへの呼び出しをログに記録することにより、アクティビティ C が開かれると、アクティビティ B が常に (予想どおり) 停止することがわかりました。 . 停止するだけであれば問題ありません。onResume が呼び出されたときに DBAdapter を定義する必要があります。ただし、アプリが長期間放置されるとアクティビティ B が破棄され、このような状況では DBAdapter (アクティビティ A の onCreate メソッドで定義) も未定義になる必要があります。

この問題の修正は if (Global.mDBAdapter== null) {Global.mDBAdapter = new DBAdapter( this, "DatabaseName" );}、アクティビティ B の onCreate メソッドに挿入することのようです。

これを正しく理解しているかどうかを確認したいと思います。SQLite データベース アダプター/ヘルパーのライフサイクル動作の変更 (Gingerbread と ICS の間) を説明するドキュメントはありますか?

4

1 に答える 1

1

正当化されていない仮定を行っていたようで、Gingerbread デバイスでたまたまそれを回避していたようです。

アクティビティのプロセスは、 が呼び出された後はいつでも強制onStop()終了できるため、 の最後にonStop()、次のライフサイクル コールバックが次の 3 つのいずれかになるように準備する必要があります。

  1. onRestart()-- プロセスが強制終了されず、Activity がすぐに再起動される場合。
  2. onDestroy()-- システムが活動を停止することを決定し、通知することが都合がよい場合。
  3. onCreate()- を呼び出さずにプロセスが強制終了された場合onDestroy()

(ハニカム前、プロセスは後でも強制終了可能onPause()です。)

つまり、Activity C から長期間離れていると、プロセス全体が強制終了されるということです。アクティビティ C に戻って BACK を押すと、アクティビティ B はonCreate()-> onStart()->を通過onResume()し、アクティビティ A によってグローバルな状態が設定されていると想定しているように見えますが、そうではありません。

これは Gingerbread と ICS の間の変更ではありません。あなたはちょうど前に運が良かった.

読んで理解するための優れたリソース:

更新:以下のコメントで、アプリケーションが破棄されたときに Android がアプリケーションの状態について正確に何を保持するかを尋ねました。私の印象では、基本的にはアクティビティ スタックと のバンドルだけonSaveInstanceState()です。(どのアクティビティが開いていたかは特に覚えていません。それはスタックの一番上にあるだけです。)これは理にかなっています。Android はその最後(アクティビティ スタック)を処理し、あなたは自分のものを処理します(最も重要なものを保存し、準備を整えることによって)。残りを再作成します)。

のデフォルトの実装はonSaveInstanceState()、すべてのビューで同じ名前のメソッドを呼び出します。これにより、一部のデータが無料で保存および復元されているように見える場合があります。ただし、そのメソッドをオーバーライドしないと、静的であろうとなかろうと、独自のデータ メンバーが保存されることはありません。これは私にとって非常に理にかなっています。自動的にそうすると反射が必要になり、効率が悪く、無駄が多く、非常に混乱します。保存すべき重要なものを保存するのはあなた次第です。Android には、これを簡単にするためのコールバックが用意されています。

別のリソースを次に示します。

onSaveInstanceState()ただし、必ずしも に対処する必要はありません。データベース アダプタなど、再作成するほうが理にかなっているものもあります。

于 2012-07-03T21:55:51.790 に答える