22

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

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

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

4

6 に答える 6

26

どのエミュレーターでテストしているかはわかりませんがフォーカスを失ったときに常にonPause呼び出されることが保証されているメソッドの 1 つです(特に Android 3.2 以降を実行している一部のデバイスでは、が破棄される前に呼び出されます)。ActivityonStopActivity

初心者がライフサイクルを理解する良い方法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 -");
    }
}
于 2012-07-08T22:57:30.243 に答える
13

あなたの質問が6か月前のものであることは知っていますが、他の誰かがこの質問に出くわした場合に備えて:

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

はい、そうです。これ:

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

ホームボタンを押すと実際にonPause()メソッドが呼び出されますが、ホームボタンを押すとアクティビティが表示されなくなるため、メソッドが呼び出されますonStop()(愛国者と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()、ここでは一般的なケースについて話しているだけです。

于 2013-04-03T13:49:59.173 に答える
4

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

于 2012-07-08T22:46:38.680 に答える
2

onPause():

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

onStop():

「アクティビティが別のアクティビティによって完全に隠されている場合、アクティビティは停止します。すべての状態とメンバー情報は引き続き保持されますが、ユーザーには表示されなくなるため、ウィンドウは非表示になり、メモリが失われるとシステムによって強制終了されることがよくあります。他の場所で必要です。」

Android リファレンス アクティビティ クラスから取得: http://developer.android.com/reference/android/app/Activity.html

于 2012-07-08T22:59:38.073 に答える
1

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

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

于 2012-07-08T23:06:58.683 に答える
1

ミルターさんに同意!

onPause():

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

Back を押さずに (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」など...

于 2013-06-09T17:00:40.387 に答える