web-dev-qa-db-ja.com

Android:どのような状況でダイアログが表示されるとonPause()が呼び出されますか?

Android Activities document(「foreground lifetime」までスクロールダウンして)行)言う:

アクティビティは、頻繁にフォアグラウンドに出入りできます。たとえば、onPause()は、デバイスがスリープ状態になったときに呼び出されますまたはダイアログ表示されます

これはよくわかりません。これはどのような状況で発生しますか? onPause()は、問題のダイアログのコンテキストが、ダイアログを表示するアクティビティと異なる場合にのみ呼び出されますか?

編集:私の疑問を詳細に説明するためにコードサンプルを追加する

上記のドキュメントからの引用に沿って、私のアクティビティのonPause()メソッドは、次のコードのAlertDialog(または単にDialog)が表示されたときに呼び出されるべきですか?ダイアログが表示されたときに「onPause called」ログエントリを表示する必要がありますか?

しかし、私はそれが起こるとは思わない。そして、Androidライフサイクルを正しく理解していれば、それもそうではないはずです!それでは、そのドキュメントは何を指しているのでしょうか?

public class LifeCycleTestActivity extends Activity {

    private static final String TAG = "LifeCycleTest";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button btn = (Button) findViewById(R.id.button1);

        btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Log.d(TAG, "onClick");

                AlertDialog dialog = new AlertDialog.Builder(LifeCycleTestActivity.this).create();
                 dialog.setMessage("You Clicked on the button");
                 dialog.setTitle("Dialog!");
                 dialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK", new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
                 dialog.setCancelable(true);
                 dialog.show();


                /*
                Dialog dialog = new Dialog(LifeCycleTestActivity.this);
                 dialog.setTitle("Dialog!");
                 dialog.setCancelable(true);
                 dialog.show();
                */
            }
        });        
    }

    @Override
    protected void onPause() {
        Log.d(TAG, "onPause() called");
        super.onPause();

    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume() called");
    }
}
72
curioustechizen

onPause()は、アクティビティがアクティビティスタックの一番上になくなったときに呼び出されます。ダイアログ自体はアクティビティではないため、スタックの最上部にある現在のアクティビティを置き換えることはないため、何も一時停止しません。

ただし、ダイアログ(小文字)は、Dialogクラスによって実装する必要はありません。たとえば、テーマがダイアログのテーマに設定されているアクティビティを持つものを実装することは珍しくありません。この場合、dialog-as-an-Activityを表示すると、新しいアクティビティがスタックの一番上になり、以前にあったものが一時停止します。

174
hackbod

私はあなたが言及したAlertDialogを含むダイアログで非常に多くのコードを行ってきました。また、ダイアログが表示されたときにアクティビティでonPause()が呼び出されているかどうかを確認しようとしましたポップアップが表示されますが、これまでのところ私の結論は、アクティビティが単に実行を続け、onPause()呼び出されません

それが役立つかどうかはわかりませんが、少なくともあなたは今あなたが経験していることを経験している他の人がいることを知っています:-)

12
Michell Bak

OnPauseフェーズでアクティビティがアクティビティスタックの最上部に留まらないというのは間違っています。

アクティビティをonPause状態にする条件-

  • 部分的に見えるアクティビティアクティビティに関するダイアログ。
  • Activityオブジェクトはメモリに保持され、すべての状態とメンバー情報を維持し、ウィンドウマネージャーにアタッチされたままになります。

    たとえば、ホームボタンを押すと、アクティビティがonPause()に入ります。スタックの一番上にあります。

図1では、Activity3が破棄され、一番上のスタックから削除されます

図2では、タスクAはバックグラウンドになりますが、Activty Xはスタックの一番上にあります。この状態でonPause()メソッドをオーバーライドすると

enter image description here

図1.タスク内の各新しいアクティビティがバックスタックにアイテムを追加する方法の表現。ユーザーが[戻る]ボタンを押すと、現在のアクティビティが破棄され、前のアクティビティが再開されます。

enter image description here

図2. 2つのタスク:タスクBはフォアグラウンドでユーザーインタラクションを受け取り、タスクAはバックグラウンドで再開を待機しています。

2
Yuvraj Kakkar

以前のバージョンのAndroidライフサイクルで、アクティビティが表示されていないときにonPauseが呼び出されたことを思い出したと思います。つまり、アクティビティの一部がポップアップ、onPause呼び出されません。

他の専門家がこの動作を保証できるかもしれませんか?

0
FrinkTheBrave

私の少し奇妙な経験では、onResumedialog.setCanceledOnTouchOutside(true);で呼び出されますが、onPauseは呼び出されません。

そうは言っても、ドキュメントはシステムダイアログに焦点を当てているかもしれません(たとえば、バッテリー不足)。

0
Karl

@hackbot

onPause()は、アクティビティがアクティビティのスタックの一番上になくなったときに呼び出されます。ダイアログ自体はアクティビティではないため、スタックの最上部にある現在のアクティビティを置き換えないため、何も一時停止しません。

すべては実装に依存します...

aダイアログとは何ですか? WindowはWindowManager ///によってDisplayに追加されるため、表示されるウィンドウはすべての上にあります....(Zオーダー)

activity ...とは、ウィンドウを作成する「もの」です....

ダイアログが表示されるか、ウィンドウが既存のアクティビティの上に表示されると、アクティビティウィンドウの一部がオーバーライドされるため、既存のアクティビティは部分的に非表示の状態に移行し、onPause( )ActivityThreadから。

しかし、私たちもここで考える必要があることを確認するために...

ウィンドウの状態は、スタンドアロンウィンドウが上部に表示されるか、それが子ウィンドウおよびその親である場合アクティビティウィンドウです。...

だから私たちが知っているとき

  • 追加するために使用するWindow.LayoutParams(FLAGS)
  • そして、どのIBinderがウィンドウの表示に使用されるか

各ウィンドウにはコールバックがあり、アクティビティまたはダイアログで管理するために使用されます彼らの状態...

関連するコンポーネント:

  • Android.os.IBinder

  • Android.view.Window

  • Android.view.Window.Callback

  • Android.view.WindowManager

  • Android.view.WindowManager.LayoutParams

  • Android.view.Display

ところで:

画面上のウィンドウを知りたい場合[所有しているプロセスにのみ適用-ウィンドウはプロセスに属し、それらはサンドボックス化されます-各プロセスは個別のJVMで厳密に「ART」と言います]

  • Android.view.WindowManagerImpl
  • Android.view.WindowManagerGlobal
0
ceph3us