5

現時点では、Android のライフサイクル管理について少し混乱しています。アクティビティがフォアグラウンドに戻った後、保持されたデータを再開するには、少なくとも 4 つの可能性があります。

  • Android の処理:十分なメモリがある場合、アクティビティの再起動後、Android は重要なデータ (チェックされたラジオ ボタン、EditText のテキストなど) を保存して再開します。ユーザーは、アクティビティが開始されたときと同じ状態になります。バックグラウンド。

  • onPause、onResume: onPause をオーバーライドし、重要なデータをデータベースまたはテキスト ファイルに保存し、次回の onResume 実行時に再開します。

  • onSavedInstance(Bundle)、onRestoreInstance(Bundle):データをキーと値のペアとしてバンドルに保存し、onRestoreInstance の実行後にそれらを復元できます。

  • onRetainNonConfigurationInstance()、getLastNonConfigurationInstance():ストレージの問題をすべて 1 つの大きなオブジェクトで処理し、onCreate の実行時に getLastNonConfigurationInstance() を読み取ります。

どのアプローチが最適かは混乱しますが、いつどの可能性を使用するかを知るには、開発経験に依存していると思います。それぞれの良い例があればうれしいですが、これは私の質問ではありません。さまざまなアクティビティがあり、バックグラウンドで一時停止すると Android によって 1 つのアクティビティが強制終了される場合、これらすべてにどのように対処すればよいのでしょうか。

私の場合、MainActivity と MessageActivity があります。MessageActivity は、2 つの状態で構成される ViewSwitcher で構成されます。状態 1 は、ラジオ ボタンの選択リストです。状態 2 は、2 つのボタン (送信と中止) を持つ EditText です。各状態をモンキーテストし、Android のホームボタンを押してアプリケーションを再起動すると、適切な状態の適切なアクティビティと古いデータがフォアグラウンドになり、処理を Android に任せます。それでうまくいきます。
しかし、Android がバックグラウンドで MessageActivity を破棄するとどうなるか: Android の方法を使用すると、データが失われ、次にアプリケーションを再起動した後に (MessageActivity->state(1 または 2) ではなく) MainActivity が開始されると思います (それは正しいですか?)。したがって、MessageActivity のデータを保持したい場合は、他の 3 つの可能性のいずれかを使用する必要があります。
アプリケーションのエントリ ポイント (つまり MainActivity) が最後のアクティブなアクティビティと異なる場合に、これを適切に行う方法。問題は、ViewSwitcher の特別な状態で特別なアクティビティを再開する必要があることです。onStart() または onResume() メソッドで startActivity(Intent) を使用して MainActivity から MessageActivity を開始できますが (MainActivity がおそらくエントリ ポイントであるため)、ライフサイクル管理で多くの論理的な問題が発生します。この事実のため、これが正しい方法だとは思いません。

しかし、それを行うための正しくて最良の方法は何ですか?

4

4 に答える 4

2

ベストアンサーを目指しているわけではありませんが、コメント セクションに入れるには長すぎます。

最初に、「Android のやり方」に頼らないことをお勧めします。これは、デバイスの空きメモリに応じてアプリケーションの動作に一貫性がなくなります。悪い習慣です。

私の提案は、状態に依存するデータをキーと値のペアで保存するSharedPreferencesことonPause()ですMessageActivity。最後に開いたアクティビティを示すフラグを にSharedPreferences保存します (アクティビティが 2 つしかない場合は、0/1 または true/false フラグを簡単に設定できます)。アプリケーションを再起動すると、通常、AndroidManifest.xml で「エントリ ポイント」としてマークされたアクティビティが開始されます。したがって、当然、フラグをチェックインし、必要に応じて他のアクティビティを開始しonResume()ます。値を確認し、必要なものを入力してください...アプリケーションが ActivityStack の最後のアクティビティに「再開」されている場合、MainActivityこれはActivityStack最後のアクティビティを呼び出します。MessageActivity's onResume()SharedPreferencesonResume()

于 2012-01-05T18:03:33.563 に答える
2

アプリケーションを再起動した後、MainActivity (MessageActivity->state(1 or 2) の代わりに) が次回開始されると思います (正しいですか?)

いいえ、onCreate() でのコードの動作によっては、これが正しいとは思いません。正しい方法で物事を進めれば、必ずしも正しい必要はありません。これをテストする簡単な方法は、デフォルトの構成変更動作をオーバーライドしていない限り、実行中のアクティビティを再作成する画面を回転させることです。

Android ドキュメントのこのセクションを注意深く読むことをお勧めします。

http://developer.android.com/guide/topics/fundamentals/activities.html#SavingActivityState

特に:

何もせずに onSaveInstanceState() を実装しない場合でも、アクティビティの状態の一部は、onSaveInstanceState() の Activity クラスのデフォルト実装によって復元されます。具体的には、デフォルトの実装は、レイアウト内のすべてのビューに対して onSaveInstanceState() を呼び出します。これにより、各ビューは、保存する必要があるそれ自体に関する情報を提供できます。Android フレームワークのほぼすべてのウィジェットがこのメソッドを適切に実装しているため、UI に表示される変更は自動的に保存され、アクティビティが再作成されたときに復元されます。たとえば、EditText ウィジェットはユーザーが入力したテキストを保存し、CheckBox ウィジェットはチェックされているかどうかに関係なく保存します。必要な作業は、状態を保存するウィジェットごとに一意の ID (android:id 属性を使用) を指定することだけです。ウィジェットに ID がない場合、

つまり、呼び出しで UI の状態を強制しない限りonCreate()、アクティビティ スタックと UI の状態が復元されます。

個人的には、アクティビティのメンバー変数にできるだけ少ない状態を保持し、それを で保存および復元しonSave/RestoreInstanceState()、残りの UI 状態 (テキスト ボックスの内容など) を保存するために既定の実装に依存することをお勧めします。セッション間で保持する必要があるデータは、DB または設定が変更されるとすぐに (たとえば、オンクリック ハンドラーで) 直接コミットします。これは、アクティビティのライフサイクルについて心配する必要がないことを意味します。可能な限り、UI は DB 内のデータのビューを表示するだけです (CursorAdapter などを使用)。

編集:

アクティビティスタック全体の復元について:

ユーザーが HOME キーを押してタスクを終了すると、 ... システムはタスク内のすべてのアクティビティの状態を保持します。ユーザーが後でタスクを開始したランチャー アイコンを選択してタスクを再開すると、タスクはフォアグラウンドに移動し、スタックの一番上でアクティビティを再開します。

( http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.htmlを参照)

于 2012-01-05T20:03:22.220 に答える
1

私が過去にこのような問題を処理した方法は、インテントとリスナーのいずれかを介してさまざまなアクティビティからの情報の流れを処理するサービスをバックグラウンドで実行することです (これらは最も簡単に分離できるソリューションであるため、推奨されます)。または、細心の注意を払い、何らかの理由で実行可能な唯一の解決策が、プロパティへの直接アクセスまたはメソッド呼び出しを介してデータを格納することである場合は、サービス クラスでも静的プロパティ/メソッドを使用できます。ただし、インテント/リスナー メソッドを使用することを強くお勧めします。これは、一般的に柔軟性が高く、スレッド セーフであり、分離されているためです。さらに、どの時点でも多くのことが起きていないことを確認することが賢明です (つまり不要な場合は、このサービスをインテント処理に使用してください)。そうしないと、実際には必要ない場合でも、サービスは RAM だけでなく CPU 時間も浪費する傾向があります。

このアプローチに関して注目すべきいくつかのリソースは、IntentServiceとその関連クラス (スーパークラスの Service を含む) です。ただし、IntentService は、Service に自動的に付属しない非同期 Intent 処理などについて、さらにいくつかのことを処理することに注意してください。

これがお役に立てば幸いです!

于 2012-01-05T18:02:46.833 に答える
1
login.setOnClickListener(new View.OnClickListener()      {
    public void onClick(View view)         {
        String name=username.getText().toString();
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        SharedPreferences.Editor editor = settings.edit();
        editor.putString("username", name);
        if(name.equals("xxx"))                 {
            Intent intent=new Intent(currentactivity.this,nextactivity.class);
            intent.putExtras(bundle);
            startActivityForResult(intent,0);
        }
    }
});
于 2012-02-18T06:59:46.717 に答える