3

複数のアクティビティを含むアプリケーションがあります。

現時点では、アプリケーション全体に約 8 つのアクティビティが含まれています。最初に、(sharedPreferences から) すべての設定が読み込まれて設定されるスプラッシュ スクリーンを数秒間表示します。これらは、このために作成した「設定」クラスに保存されます。アプリ内のすべてのアクティビティは、これらを読み取り、必要に応じて変更できます。

EDIT :アプリの実行時に、このクラスに保存されるデータが増えます。その一部は Web サービスからのものです。データはオブジェクトに解析され、これらのオブジェクトへの参照も設定クラス (またはオブジェクトのリスト) に保存されます。

私の問題は、ユーザーが HOME キーを押すと、現在のアクティビティがバックグラウンドに置かれることです。アクティビティが長時間バックグラウンドにあり (多くのユーザーは戻るのではなくホームを押してアプリを「閉じます」)、再度開くと、ホームが押される前に実行されていたアクティビティが表示されます。

例として、ユーザーがアプリを起動し、スプラッシュ画面が数秒間表示されたとします。その後、スプラッシュ スクリーンは新しいアクティビティを開始し、finish を呼び出します。

これは、Activity スタックが単なる MainActivity (メイン メニュー) であることを意味します。MainActivity では、すべてのボタンに onCreate メソッドのリスナーを指定します。ほとんどのボタンには、上記の Settings クラスからの情報が必要です。

次にホームを押して数時間後にアプリを再度開くと、どのボタンも機能しなくなります-グラフィックが反応しているように見えますが、それでも何か問題が発生します. すべての設定が消去された状態でも機能するはずのボタンの 1 つは、テキストを含むダイアログを開くだけです。

リスナー:

Button b = (Button)v.findViewById(R.id.id_b1);
b.setOnClickListener(new OnClickListener() {
  public void onClick(View v) {
    Dialog dialog = createDialog(MainActivity.this, DIALOG_CONST1);
    dialog.show();
  }
});

ダイアログにいくつかのカスタムデザインを使用しているため、ダイアログを作成するためのクラスを作成しました。

ボタンを含むアクティビティから (少し簡略化):

public static Dialog createDialog(final Context c, int dialogId) {
  Dialog dialog = null;
  CustomDialog.Builder customBuilder;
  switch (dialogId) {
    ...
    case d1:
      customBuilder = new CustomDialog.Builder(c, DIALOG_CONST1);

      //Sets up the parapters to create the dialog afterwards
      customBuilder.setTitle("Header").setMessage("Content")
      .setPositiveButton("", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
          dialog.dismiss();
        }
      });
      dialog = customBuilder.create(); //Creates the dialog from the above settings
      dialog.setCanceledOnTouchOutside(true);
      break;
    ...
  }
  ... //Set the width of the dialog
  return dialog;
}

CustomDialog クラスは Dialog クラスを拡張し、それが提供する const に応じて、いくつかのダイアログ レイアウトの 1 つを拡張し、コンテンツなどを追加します。正常に動作しますが、アプリが HOME によってしばらく一時停止された後、問題が発生しますボタンを押してもダイアログは表示されません。他のボタンでロード ダイアログのフラッシュが表示されますが、その後何も起こりません。ダイアログは表示されません。奇妙なことに、画面の中央でもう一度ボタンを押すと、ボタンを押すことができません (グラフィックは反応しません)。外側を押すとダイアログがキャンセルされるので、真ん中か何かに非常にスリムな「透明な」ダイアログがあるのではないかと思っています-なぜこれが起こるのかわかりません。

編集:実際に設定クラスに保存した変数を調べてみると、画面の幅と高さをピクセル単位で保存していることがわかります。カスタム ダイアログの幅を画面幅の特定の % に設定するために使用される幅。設定がワイプされた場合、幅が 0 に設定されているためにダイアログが表示されない理由を説明できるかもしれません...設定クラスのすべての変数がワイプされない場合、何が起こっているのか本当にわかりません-すべてが本当にそれを指しています。

dialog.getWindow().setLayout(Settings._widthpx - (Settings._widthpx/5), dialog.getWindow().getAttributes().height); //Width = 80%

実際、私は Android にかなり慣れていないため、何が原因なのかよくわからないことを認めなければなりません。Settings クラスが使用されていない場合、しばらくすると GC がすべての変数を削除すると思われます。ユーザーが数時間後に戻ったときにすべての設定が消去されます。ただし、これはボタンが機能しない理由を説明していません (そのうちの 1 つは設定を必要としません)。

このメイン アクティビティは他のアクティビティを開始することができ、これらは再び新しいアクティビティを開始することができます。

HOMEが押されたときにアプリ全体を強制的に閉じて、アイコンが押されるたびにアプリを最初から強制的に開始することができれば、すべての問題を解決できると思います-ボタンのリスナーと設定のロードを強制します.

「android:clearTaskOnLaunch」、「android:launchMode」、および「android:finishOnTaskLaunch」についてここで読みましたが、これらを正しく使用する方法がよくわかりません。

ボタンが機能しない理由、またはアプリがしばらくバックグラウンドにあるときに設定クラスの変数に何が起こるかを説明できる人、または使用方法に関するいくつかの良いヒントを教えてくれる人「アクティビティ」が適切に設定されています。

編集:アプリはAndroid 1.6以降を実行するため、新しい機能などは使用できません...

どうもありがとうございました

4

5 に答える 5

3
  • ホーム キーの機能を上書きしないでください。たぶん、どこかでこれを可能にする何かを見つけるでしょう。神を恐れ、標準を採用するアプリケーションは、決してホーム キーをオーバーライドしません。
  • マニフェストに android:clearTaskOnLaunch=true を入れるだけです。これにより、ランチャー アイコンを押すたびにメイン アクティビティが起動されるようになります。

Settings クラスが使用されていない場合、しばらくすると GC がすべての変数を削除すると思われます。ユーザーが数時間後に戻ったときにすべての設定が消去されます。

  • Android は、あなたのアプリにこれを行うのはそれほど悪いことではありません。アプリケーション、サービス、およびバックグラウンドで実行されているものは、しばらく非アクティブになった後、および/またはより多くのメモリが必要になった後に強制終了される可能性がありますが、変数なしでアプリケーションがハングしたままになることはありません。
于 2012-04-10T15:07:23.597 に答える
0

Android 4.0以降を使用している場合は、開発者向けオプションで[アクティビティを保持しない]を有効にできます。4.0デバイスをお持ちでない場合は、エミュレーターを使用してください。

于 2012-04-10T14:36:04.170 に答える
0

ホームボタンの現在のアクティビティの上にあるすべてのアクティビティを強制終了する必要があり、そのためには、書き込む必要があるホームキー機能をオーバーライドする必要があります

Intent intent = new Intent(context,login.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

これにより、ホームキーを押してログインアクティビティに切り替えるアクティビティの上にあるすべてのアクティビティがクリアされ、

ホームキーの機能をオーバーライドしたくない場合は、Androidmanifest.xmlandroid:clearTaskOnLaunch=trueを 1 つだけ記述する必要があります。アプリのアイコンをクリックすると、最初のアクティビティが開始されます。

2番目のアプローチがあなたに最適であることをお勧めします。

于 2012-05-15T06:57:27.007 に答える
0

後世のために、私のアプリでは、finish();を追加しました。私がそこで行ったすべての後の onStop()メソッドで、それは魅力として機能しました。

于 2012-10-03T21:39:28.910 に答える
0

私は実際に Android 2.0 開発 2.0 用にこれをカスタマイズしました。より良いオプションが利用できるようになったかもしれません。アクティビティは、グローバルにのみ宣言されます。アクティビティは、使用される場合にのみ定義されます。

于 2012-04-10T14:31:00.337 に答える