Android ActivitesのonPause()とonStop()の違いは何ですか?


149

android doc here http://developer.android.com/reference/android/app/Activity.htmlから、「アクティビティがフォアグラウンドに入りました」が呼び出されonPause()、「アクティビティが表示されなくなりました」が呼び出されると述べましたonStop()

「アクティビティが前面に表示される」と「アクティビティが表示されなくなる」は同じではありませんか?それらの違いは何ですか?


17
優れた質問の+1。また、pausedアクティビティは完全に生きています(すべての状態とメンバー情報を維持し、ウィンドウマネージャーに接続されたままです)。また、stoppedアクティビティはすべての州とメンバーの情報を保持しますが、には関連付けられなくなりwindow managerます。
ateiob 2012

回答:


107

いいえ、あるアクティビティが前面に出ても、必ずしも他のアクティビティが完全に見えないというわけではありません。次のケースを考えてみましょう:

Theme.Dialogをテーマにしたアクティビティ

ここでは、両方のアクティビティが同時に表示されます。フィールドを持つ最初のアクティビティは別のアクティビティによって隠され、ユーザーはそれを操作できなくなります。ただし、結果はすべて表示されたままです。

これは、どのアクティビティが完全に不透明であり、画面全体を覆っていると見なされるか、そうでないかという疑問を残します。この決定は、アクティビティを含むウィンドウに基づいています。ウィンドウにフラグwindowIsFloatingまたはがある場合、windowIsTranslucentアクティビティは基になるものを非表示にしないと見なさonStop()れます。それ以外の場合は、呼び出されて呼び出されます。関連するコードは次の場所にありますcom.android.server.am.ActivityRecord

fullscreen = ent != null && !ent.array.getBoolean(
        com.android.internal.R.styleable.Window_windowIsFloating, false)
        && !ent.array.getBoolean(
        com.android.internal.R.styleable.Window_windowIsTranslucent, false);

10
+1は、部分的な可視性と全体的な(非)可視性に焦点を当てた優れた説明です。Androidの間決めるになり、画面のしきい値の割合を知るために興味深いものになるだろうonPause()としonStop()。100%ですか?前のアクティビティの1ピクセルのみが表示されている場合、それはまだonPause()ですか?
ateiob 2012

3
@ateiobどこにも言われていませんが、そう思います。ただし、画面全体に表示されないほとんどのアクティビティは、システムが提供するダイアログのスタイルの1つを使用するだけなので、通常は明らかです。
Malcolm

1
奇妙ですが、私のアプリケーションでonPause()は、ダイアログが表示されたときにまったく呼び出されません。ホームボタンonPause()を押したときにのみ呼び出されます。これはどのようにして可能ですか?
ateiob 2012

これが正解です。ちなみに前景は対話か活動か?
GMsoF 2012

3
@GMsoFアクティビティ。それが主なポイントです。すべてのダイアログが実際にダイアログであるとは限りません。アクティビティをダイアログのように見せることができるため、実際には画面全体よりも小さくなります。
Malcolm

38

それでもその一部が見える場合(Activityフォアグラウンドに来ると、画面全体を占有しないか、いくらか透明にonPause()なります)が呼び出されます。あなたがそれの一部を見ることができないならば、onStop()呼ばれます。

たとえば、ダイアログ**は以前の全体をカバーしない場合がありActivity、これはonPause()呼び出される時期です。

**ここでは、Android Dialogについて言及しているのではなく、ポップアップしてユーザー画面の一部を覆い隠すだけの概念的な概念を示しています。このメモは、以下の@GMsoFからのコメントに基づいて明確にするために追加されました


33
番号。これは誤解を招くものです。ダイアログが現在のアクティビティのコンテキストを使用するため、表示されたダイアログはonPause()を呼び出しません。アクティビティは生きていると考えてください。
GMsoF

6
@GMsoF私がダイアログを言ったときDialog、Androidクラスのように、あなたは私がを意味すると思ったようです。しかし、私が得ていたのは、Activityすべてのnew Activityが前のものを完全にカバーする必要はないという考えを説明するために、最初のものを部分的に覆い隠すものです。
nicholas.hauschild

11

フォアグラウンドにあるということは、アクティビティに入力フォーカスがあることを意味します。たとえば、アクティビティは表示できますが、フォーカスのあるダイアログによって部分的に隠れることがあります。その場合、onPause()は呼び出されますが、呼び出されませんonStop()。ダイアログが消えると、アクティビティのonResume()メソッドが呼び出されます(は呼び出されませんonStart())。


5
ダイアログのことは誤解を招く可能性があります。警告ダイアログがこのアクティビティのメインUIスレッドからポップアップされるとしましょう。この場合、onPause()は呼び出されません。このダイアログが他のアクティビティまたは他のアプリからポップアップされた場合のみ。
Sam003

1
@Zhisheng-私はあなたのコメントに同意します。私はちょうど言い換えたのactivitesガイドトピックonPause()デバイスがスリープ状態になったときに呼び出されたりすると、ダイアログが表示されています」このスレッドが明らかになり、しかし、ダイアログはしません必ずしも(それは、たとえば、ためになるものの、活動が一時停止されていることを意味するダイアログとして示さ活動)。
テッドホップ2015

9

実際には「onPause()」「onPause()+ onStop()」違いを考慮する必要があります。

新しいアクティビティが発生し、画面の一部のスペースを占有する場合。そのため、以前に実行したアクティビティは、まだある程度見えています。この場合、以前に実行されていたアクティビティはバックスタックにプッシュされません。したがって、ここではonPause()メソッドのみが呼び出されます。

一方、新しいアクティビティが発生してフルスクリーンを占めると、以前に実行していたアクティビティは表示されなくなります。この場合、以前に実行していたアクティビティはバックスタックに移動されます。ここでは、onPause()+ onStop()が呼び出されます。

要約へ-

onPause() -画面は他の新しいアクティビティによって部分的に覆われています。アクティビティはバックスタックに移動されません。

onPause()+ onStop() -画面は他の新しいアクティビティで完全に覆われています。アクティビティはバックスタックに移動されます。

バックスタックについてもっと知る。


0

簡潔に言えば:

onStop()別のアクティビティが表示されると、前のアクティビティのライフサイクルメソッドが呼び出されます。アクティビティの上部にダイアログがあるonPause()と、そこに呼び出されます。

:アクティビティは、画面全体に表示されるコンポーネントです。

:ダイアログは画面いっぱいに表示されないため、アクティビティではありません。


0

onPauseメソッドとonStopメソッドで多くの問題に直面したので、出会った3つのシナリオをクリアします。1
.最近のアプリボタンをクリックすると、ライフサイクルメソッドは呼び出されませんが、onWindowFocusChanged(boolean hasFocus)がhasFocus値で呼び出されますfalseとして渡されます。5より前のAndroidバージョンでは、最近のアプリボタンを押すと、onPauseメソッドが呼び出されていました。

2. Malcolmによって言及されているように、アクティビティーの上にポップアップのようなアクティビティーが表示されると、onPauseボタンが呼び出されます。画面全体を占める新しいアクティビティが呼び出されると、前のアクティビティでonStopが呼び出されます。Androidの許可ダイアログでも、アクティビティでonPauseが呼び出されます。

3。アクティビティで画面がタイムアウトすると、onPauseが呼び出されます。しばらくすると、画面を開かない場合、onStopが呼び出されます。

また、答えを完成させるateiobによって言及された1つの重要なこと

一時停止されたアクティビティは完全に有効です(すべての状態とメンバー情報を保持し、ウィンドウマネージャーに接続されたままです)。停止したアクティビティは、すべての状態とメンバーの情報も保持しますが、ウィンドウマネージャーには関連付けられません


それが役に立てば幸い。


0

新しいACTIVITYが開始するときはいつでも、前のアクティビティのアクティビティonPauseは、いかなる状況においても反抗的に呼び出されます。

実際には2つの状況があります。

1-前のアクティビティの一部が表示されているか、新しいアクティビティが透過的である:onPause呼び出されるだけです。

両方:2-以前の活性は完全に新たな活性によって覆われているonPauseonStop呼ばれます

----注意事項を記載してください:

注1:ダイアログがNONEのアクティビティの上で開始される場合、onPauseまたはonStop呼び出されない場合。

注2:テーマがダイアログに設定されているアクティビティの場合、動作は通常のアクティビティと同じです。

注3:マシュマロが発生するため、許可ダイアログのようなシステムダイアログが表示されますonPause


-5

うん、私は理解しようとし、私はこれを以下に説明することができます:

2つのアクティビティがあります:ActivityAとActivityB

public class ActivityA extends Activity implements OnClickListener {

// button
private Button mBtnChangeActivity;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_a);
    initialize();
    setEvent();
}

private void initialize() {
    Log.i("Activity A", "Initialize()");
    mBtnChangeActivity = (Button) findViewById(R.id.btn_change_activity);
}

private void setEvent() {
    Log.i("Activity A", "setEvent()");
    mBtnChangeActivity.setOnClickListener(this);
}

@Override
protected void onStart() {
    super.onStart();
    Log.i("Activity A", "onStart");
}

@Override
protected void onResume() {
    super.onResume();
    Log.i("Activity A", "onResume");
}

@Override
protected void onPause() {
    super.onPause();
    Log.i("Activity A", "onPause");
}

@Override
protected void onStop() {
    super.onStop();
    Log.i("Activity A", "onStop");
}

@Override
protected void onDestroy() {
    super.onDestroy();
    Log.i("Activity A", "onDestroy");
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn_change_activity:
        Intent activityB = new Intent(this, ActivityB.class);
        startActivity(activityB);
        break;
    default:
        break;
    }
}

これがアクティビティBです。コードでコメントをフォローしてください

public class ActivityB extends Activity implements OnClickListener {

// button
private Button mBtnChangeActivity;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_a);
    initialize();
    setEvent();
    // if call finish() here, activityA will don't stop, just pause
    // Activity A will call onStop() when Activity B call onStart() method
    finish();
}

private void initialize() {
    Log.i("Activity B", "Initialize()");
    mBtnChangeActivity = (Button) findViewById(R.id.btn_change_activity);
}

private void setEvent() {
    Log.i("Activity B", "setEvent()");
    mBtnChangeActivity.setOnClickListener(this);
}

@Override
protected void onStart() {
    super.onStart();
    Log.i("Activity B", "onStart");
}

@Override
protected void onResume() {
    super.onResume();
    Log.i("Activity B", "onResume");
}


@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn_change_activity:
        finish();
        break;
    default:
        break;
    }
}
}

これが明確であることを願っています


常に、それが理にかなっていると説明しよう
アレクサンダーザルドスタノフ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.