web-dev-qa-db-ja.com

アクティビティのonPause()およびonStop()

Android開発に慣れていないのに、アクティビティのonPause()メソッドとonStop()メソッドをまだ理解できません。

私のアプリには、Counterという名前の静的クラスがあり、アプリのメモリ内の変数の状態を保持しています。エミュレータでアプリが正常に動作します。私がテストしようとしていたのは、onPause()onStop()の動作の違いです。

onPauseの場合、Counterクラスのメンバーに保存されている値を保持したいのに対して、onStop()を呼び出すと、カウンターの値をゼロにリセットしたかったのです。そこで、onStop()をオーバーライドし、カウンタークラス内の変数をゼロに設定します。ただし、エミュレーターでは、アプリを一時停止状態にすることはできません。エミュレーターで、アプリを開いて実行します。次に、エミュレータの(戻るボタンではなく)ホームボタンを押し、別のアプリを起動します。これはonPause()アクティビティを模倣すると信じています。ただし、エミュレーターはこれを尊重していないようです(私はarmeabi v7aエミュレーターを使用しています)。onStop()のオーバーライドごとに、カウンター値がすべてゼロに戻るため、常にonStop()を呼び出しているようです。これはエミュレータに固有のものですか、それともアクティビティを一時停止状態にするために何か間違ったことをしていますか?

19
Stephan Doliov

どのエミュレータでテストしているのかわかりませんが、onPauseは1つのメソッドですalwaysActivityがフォーカスを失ったときに呼び出されることが保証されます(そして- 常に一部のデバイス、特にAndroid 3.2+、onStopは、Activityが破棄される前に必ず呼び出されるとは限らないため] 。

初心者向けのActivityライフサイクルを理解する良い方法は、オーバーライドされたメソッドをLogsでポイ捨てすることです。例えば:

public class SampleActivity extends Activity {

    /**
     * A string constant to use in calls to the "log" methods. Its
     * value is often given by the name of the class, as this will 
     * allow you to easily determine where log methods are coming
     * from when you analyze your logcat output.
     */
    private static final String TAG = "SampleActivity";

    /**
     * Toggle this boolean constant's value to turn on/off logging
     * within the class. 
     */
    private static final boolean VERBOSE = true;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (VERBOSE) Log.v(TAG, "+++ ON CREATE +++");
    }

    @Override
    public void onStart() {
        super.onStart();
        if (VERBOSE) Log.v(TAG, "++ ON START ++");
    }

   @Override
    public void onResume() {
        super.onResume();
        if (VERBOSE) Log.v(TAG, "+ ON RESUME +");
    }

    @Override
    public void onPause() {
        super.onPause();
        if (VERBOSE) Log.v(TAG, "- ON PAUSE -");
    }

    @Override
    public void onStop() {
        super.onStop();
        if (VERBOSE) Log.v(TAG, "-- ON STOP --");
    }

   @Override
    public void onDestroy() {
        super.onDestroy();
        if (VERBOSE) Log.v(TAG, "- ON DESTROY -");
    }
}
23
Alex Lockwood

あなたの質問は6ヶ月前でしたが、誰か他の人がこの質問に出くわした場合に備えて:

アクティビティを一時停止状態にするために何か間違ったことをしていますか?.

はい、そうです。この:

エミュレーターの(戻るボタンではなく)ホームボタンを押して、別のアプリを起動します。これはonPause()アクティビティを模倣すると信じています。

ホームボタンを押すと、実際にonPause()メソッドが呼び出されますが、ホームボタンによりアクティビティが表示されなくなるため、onStop()メソッド(前述のpatriot&milterなど)が呼び出されます。

アクティビティ開発者リファレンス( http://developer.Android.com/guide/components/activities.html )に従って、ダイアログを表示するか、単にデバイスをスリープ状態にすることができます。

または、呼び出しアクティビティを部分的にしか妨害しないアクティビティを呼び出します。したがって、サイズを表示したウィンドウを作成するアクティビティを呼び出します。

_ Android:layout_width="100dp"
 Android:layout_height="100dp"
_

これは画面全体をカバーしないため、呼び出しアクティビティを部分的に表示したままにして、呼び出しアクティビティのonPause()メソッドのみを呼び出します。

両方のビューサイズが「100dp」ではなく「match_parent」になるようにそのアクティビティを複製して呼び出し、呼び出しアクティビティのonPause()メソッドとonStop()メソッドの両方が呼び出されるようにします表示されません。

もちろん、呼び出されたアクティビティがそのonCreate()onStart()、またはonResume()のいずれかでアプリのクラッシュを引き起こした場合、onStop()呼び出し元アクティビティの呼び出しは行われません。明らかに、ここでは一般的なケースについて話しているだけです。

11
Julien Rousseau

OnPause()とonStop()が呼び出されたときとの違いはかなり微妙なことができます。ただし、 here で説明したように、通常、別のactivityがフォーカスを取得するとonPause()が実行されます(ポップアップとして、または透明ウィンドウ)、現在のアクティビティがまだ実行されている間。アプリから完全に離れる場合(ホームボタンを押すなど)、アクティビティは表示されなくなり、システムはonStop()を実行する場合があります。私はアレックスが述べたようにあるため、活動が破壊される前に、onStopが呼び出されませんいくつかのケースがあることを言います。

3
patriot

onPause():

「アクティビティがフォーカスを失ったが、まだ表示されている場合(つまり、新しい非フルサイズまたは透明なアクティビティがアクティビティの上にフォーカスを持っている場合)、一時停止されます。一時停止されたアクティビティは完全に生きています会員情報とウィンドウマネージャに付着したまま)、極端なメモリ不足の状況では、システムによって殺さすることができます。」

onStop():

「アクティビティが別のアクティビティによって完全に隠されている場合、そのアクティビティは停止されます。ただし、すべての状態とメンバー情報は保持されます。他の場所で必要です。」

Android参照アクティビティクラス: http://developer.Android.com/reference/Android/app/Activity.html から取得

2
nik

Milterに同意します!

onPause():

「アクティビティがフォーカスを失ったが、まだ表示されている場合(つまり、新しい非フルサイズまたは透明なアクティビティがアクティビティの上にフォーカスがある場合)、一時停止されます。一時停止されたアクティビティは完全に生きていますメンバー情報があり、ウィンドウマネージャーにアタッチされたままになります)が、極端に低いメモリの状況ではシステムによって殺される可能性があります。

[戻る]を押さずに(HOMEを押したまま)アプリケーションを交換すると、OSはonPauseを呼び出します。 onResumeでアクティビティに戻る(HOMEをもう一度押したままにする)ときは、プライベート変数をすべて保持する必要があります。しかし、ユーザーを制御することはできませんよね!

ユーザーがアプリを離れ、OSがonStopを呼び出すと予想される場合、中断した場所から再開する場合はデータを保存する方が適切です。

タイマーもあります。ユーザーが戻ったときにデータを復元できるように、経過時間を保存する必要があります。ここに保存する私の例があります:

@Override 
public void onSaveInstanceState(Bundle savedInstanceState) { 
  super.onSaveInstanceState(savedInstanceState); 
  // Save UI state changes to the savedInstanceState. 
  // This bundle will be passed to onCreate if the process is 
  // killed and restarted. 

  savedInstanceState.putLong("elapsedTime", elapsedTime);
  // etc. 
} 

そして復元する私のコード:

@Override 
public void onRestoreInstanceState(Bundle savedInstanceState) { 
  super.onRestoreInstanceState(savedInstanceState); 
  // Restore UI state from the savedInstanceState. 
  // This bundle has also been passed to onCreate. 

  elapsedTime = savedInstanceState.getLong("elapsedTime");
} 

これらのメソッドをクラス内に配置すると、準備完了です。私の場合、文字列「elapsedTime」はシステムのキーであり、一意でなければならないことに注意してください。保存する各データに一意の文字列を使用します。たとえば、「startClock」、「ClockTextColor」など...

1
Gilson

Android 4.xをエミュレートしている場合、[設定]-> [開発者オプション]-> [アクティビティとバックグラウンドプロセス制限を保持しない]を使用してバックグラウンドアクティビティの処理方法を制御できます。同じ設定を含むDev Toolsというアプリですが、メモリが少ない状態では、システムはこれらの設定を無視してアプリケーションを終了できます。エミュレータに割り当てられたメモリの量を増やすと役立つ場合があります。

また、Eclipseからアプリを再起動する場合、前のプロセスを正常に終了する代わりに強制終了します。

1