web-dev-qa-db-ja.com

onResumeが2回呼び出されるのはなぜですか?

基本的に、これは私がやっていることです

1)BroadcastReceiver(BCR)を実行するようにAlarmManagerを設定します

Intent intent = new Intent(m_Context, BCR.class);  
intent.putExtras(extras);  
PendingIntent pendingIntent = PendingIntent.getBroadcast(m_Context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);  
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, StartTime, pendingIntent)  

2)BCRからMyActivityを開始します

@Override  
public void onReceive(Context context, Intent intent) {  
    Intent newIntent = new Intent(context, MyActivity.class);
    newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);  
    context.startActivity(newIntent);  
}

3)MyActivityの画面がオンになっていない場合はオンにします

@Override  
public void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState); 
    getWindow().addFlags(LayoutParams.FLAG_DISMISS_KEYGUARD);
    getWindow().addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED);
    getWindow().addFlags(LayoutParams.FLAG_TURN_SCREEN_ON);
    setContentView(R.layout.myactivity);  
} 

@Overide  
protected void onNewIntent(Intent intent) {  
    super.onNewIntent(intent);  
}  

何らかの理由で、MyActivityを開くと、フローは次のようになります。

onCreate/onNewIntent-> onResume-> onPause-> onResume

すぐにonPauseを実行する理由がわかりません。これは、フラグによってスクリーンがオンになっている場合にのみ発生します。なぜこれが起こるのか誰にも分かりますか?この動作を防ぐ方法はありますか?

43
Huy T

他の誰かがこれに遭遇した場合に備えて、XMLレイアウトを介してアクティビティ内でフラグメントを膨らませたときにのみ、この動作に気付くようです。この動作がフラグメントの互換性ライブラリバージョンでも発生するかどうかはわかりません(Android.app.Fragmentを使用しています)

追加されたフラグメントに対してActivity#onResumeを呼び出す前に、アクティビティがFragment#onResumeを1回呼び出し、その後Activity#onResumeを再度呼び出すようです。

  1. アクティビティ:onCreate
  2. フラグメント:onAttach
  3. アクティビティ:onAttachFragments
  4. フラグメント:onCreate
  5. アクティビティ:onStart
  6. アクティビティ:onResume
  7. フラグメント:onResume
  8. アクティビティ:onResume
29
ainesophaur

あなたが持っている場合 ES File Explorer thenFORCE STOPそれ。どういうわけか、それらはアプリのライフサイクルを中断します(コメントは何らかのオーバーレイを提案します)

onResumeが2回発生する問題は、アクティビティが作成された後にonPauseが何らかの形で呼び出されたためです。何かがアプリを中断していました。

そして、これはonlyを開いた後に発生しますインストール後初めてまたはstudioからビルド

別の投稿からclueを取得しましたが、これはES File Explorerが原因であることがわかりました。 なぜonResume()が2回呼び出されるのですか?

私がES File Explorerを強制停止するとすぐに、このしゃっくりの動作は発生しなくなります...他の多くの提案された解決策を試してみて、イライラします。したがって、他のinterruptingこのようなアプリには注意してください。

16
TWL

このような問題が発生する可能性があるたびにリクエスト許可を試行する場合は、すでに許可されているかどうかを確認してください

requestPermissionsが原因である可能性があります。

onCreate
onStart
onResume
onPause
onResume
8
user924

インターネットではこの奇妙な振る舞いについて何も言及されていないので、私はしばらくの間これについて研究していました。このダークサイドの振る舞いを克服する方法はありませんが、確かに起こる正確なシナリオを見つけました。

onPause-onResume-onPause-onResumeは、インストール後初めてアプリが起動するときに毎回発生します。コードで変更を行い、IDEからアプリを再実行(再コンパイルを含む)するだけで、この動作を呼び出すことができます。

AppCompatライブラリを使用するかどうかは関係ありません。私は両方のケースと動作をテストしました。

注:Android Marshmallow。

フラグメントとアクティビティのライフサイクルに関するこのスレッド からコードを借用しており、ここにあります(コピー、貼り付け、マニフェストでのアクティビティの宣言、フォレスト実行の実行):

import Android.app.Activity;
import Android.app.Fragment;
import Android.app.FragmentTransaction;
import Android.content.Context;
import Android.os.Bundle;
import Android.util.Log;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.TextView;

public class TestActivity extends Activity {

    private static final String TAG = "ACTIVITY";

    public TestActivity() {
        super();
        Log.d(TAG, this + ": this()");
    }

    protected void finalize() throws Throwable {
        super.finalize();
        Log.d(TAG, this + ": finalize()");
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, this + ": onCreate()");


        TextView tv = new TextView(this);
        tv.setText("Hello world");
        setContentView(tv);

        if (getFragmentManager().findFragmentByTag("test_fragment") == null) {
            Log.d(TAG, this + ": Existing fragment not found.");
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.add(new TestFragment(), "test_fragment").commit();
        } else {
            Log.d(TAG, this + ": Existing fragment found.");
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.d(TAG, this + ": onStart()");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, this + ": onResume()");
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.d(TAG, this + ": onPause()");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d(TAG, this + ": onStop()");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, this + ": onDestroy()");
    }


    public static class TestFragment extends Fragment {

        private static final String TAG = "FRAGMENT";

        public TestFragment() {
            super();
            Log.d(TAG, this + ": this() " + this);
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Log.d(TAG, this + ": onCreate()");
        }


        @Override
        public void onAttach(final Context context) {
            super.onAttach(context);
            Log.d(TAG, this + ": onAttach(" + context + ")");
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            Log.d(TAG, this + ": onActivityCreated()");
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            Log.d(TAG, this + ": onCreateView()");
            return null;
        }

        @Override
        public void onViewCreated(View view, Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            Log.d(TAG, this + ": onViewCreated()");
        }

        @Override
        public void onDestroyView() {
            super.onDestroyView();
            Log.d(TAG, this + ": onDestroyView()");
        }

        @Override
        public void onDetach() {
            super.onDetach();
            Log.d(TAG, this + ": onDetach()");
        }

        @Override
        public void onStart() {
            super.onStart();
            Log.d(TAG, this + ": onStart()");
        }

        @Override
        public void onResume() {
            super.onResume();
            Log.d(TAG, this + ": onResume()");
        }

        @Override
        public void onPause() {
            super.onPause();
            Log.d(TAG, this + ": onPause()");
        }

        @Override
        public void onStop() {
            super.onStop();
            Log.d(TAG, this + ": onStop()");
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
            Log.d(TAG, this + ": onDestroy()");
        }
    }

}
7
matusalem

何が起こっているのかはわかりませんが、画面をオンに設定することはシステムによって設定の変更として扱われるため、アクティビティが再開されていると思われます。 onResumeの呼び出しごとに構成を記録して、それが起こっているかどうか、もしそうなら実際に何が変わっているかを確認することができます。その後、マニフェストを変更して、アクティビティが変更を単独で処理することをシステムに伝えることができます。

protected void onResume() [
    super.onResume();
    Configuration config = new Configuration();
    config.setToDefaults();
    Log.d("Config", config.toString());
    . . .
}
5
Ted Hopp

同様の問題があります。私の状況は次でしたCurrentActivity extends MainActivityCurrentFragment extends MainFragment

私はCurrentActivityを通常通り意図的に開いていました。 onCreate CurrentAcitivityでは、CurrentFragmentを置き換えていました。

ライフサイクルは次のとおりです。1. onResume MainActivity 2. onResume CurrentActivity 3. onResume MainFragment 4. onResume CurrentFragment

onPauseを自動的に呼び出し、その後再び

  1. onResume MainActivity
  2. onResume CurrentActivity
  3. onResume MainFragment
  4. onResume CurrentFragment

私はすべてを再テストすることにし、数時間後に試して遊んで費やした後、根本的な問題を見つけました。 MainFragment onStartでは、毎回startActivityForResultを呼び出していました(私の場合はAndroidポップアップをWifiをオンにするためのポップアップ)。これはMainFragmentでonPauseを呼び出していました。

だからAndroidバグ、それは私のものだけです:-)

幸せなライフサイクルのデバッグ!

2
msamardzic

私は同様の問題を抱えていましたが、私の問題はonCreate()メソッドで次のことをしていたことです:

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    super.setContentView(R.layout.friends);  <-- problem
}

「スーパー」への電話。 onResume()を2回トリガーしていました。変更した後、意図したとおりに機能しました:

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.friends);  <-- 'super.' removed
}

それが役に立てば幸い。

1
Victor Lee

また、このonresume-onpause-onresumeシーケンスに遭遇しました(4.1.2以降では、2.3ではこれを経験しませんでした)。私の問題は、ウェイクロックの処理に関連していました。誤ってウェイクロックを解除するのを忘れて、それを再取得すると、「WakeLockが保留中にファイナライズされました」というメッセージが表示されます。この問題により、onResumeの直後にonPauseが呼び出され、誤った動作が発生しました。

私の提案は次のとおりです。ログのエラーを確認してください。エラーはこの問題に関連している可能性があります。

別のヒント:画面をオンにすることは、単にウィンドウフラグを使用するよりも少し難しいかもしれません。ここでこの答えを確認したい場合があります-画面が既にオンになっているかどうかを確認するレシーバーをセットアップし、次の後にのみ目的のアクティビティを起動することをお勧めします: https://stackoverflow.com/a/16346369/ 875442

0
Levente Dobson

私はこれに出くわしましたが、getWindow().addFlags()Windowプロパティの微調整が原因であるようです。

私のコードがこのようなとき

_@Override
protected void onCreate(Bundle savedInstanceState) {
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_generic_fragment_Host);
    // performing fragment transaction when instance state is null...
_

onResume()は2回トリガーされますが、requestWindowFeature()を削除すると、1回だけ呼び出されます。

0
Actine

同じ問題がありました。私は実行時にこのコードのためのものでした

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

マニフェストに入れただけです

Android:screenOrientation="landscape"

onCreateとonResumeを2回呼び出すことで問題はもうありません。

0
Boris Karloff

サポートライブラリのActivityを使用すると、インスタンスが自動的に保存および復元されるようです。したがって、savedInstanceStatenullの場合にのみ作業を行ってください。

0
yazjisuhail

基本的に多くのものがこれを引き起こします。フォーカスを失った一部の再開プロセスがそれを行うことができます。いくつかのアプリもそれを引き起こします。対処する唯一の方法は、ダブルランニングをブロックすることです。また、これには、適切な測定のために誤った一時停止がスローされることに注意してください。

    boolean resumeblock = false;

    @Override
    protected void onResume() {
        super.onResume();
        sceneView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                sceneView.getViewTreeObserver().removeOnPreDrawListener(this);
                if (resumeblock) return false;
                resumeblock = true;

                //Some code.

                return false;
            }
        });
    }

これは、こうしたことを防ぐための確実な方法です。二重再開をブロックします。ただし、メモリを保持する2つの履歴書もブロックされます。そのため、フォーカスを失っただけで、再構築する必要がない場合。それもブロックします。履歴書を使用してフォーカスの一部の変更を制御している場合、onlyフォーカスのためにそのようなものを再構築する必要があるかどうかを実際に気にするので、これは明らかに利点かもしれません。事前描画リスナーは1つのスレッドでのみ呼び出すことができ、順番に呼び出す必要があるため、ここでのコードは1回だけ実行されます。何かが適切にアクティビティ全体を破壊し、resumeblockをfalseに戻すまで。

0
Tatarize

@TWLが言ったようにES File Explorerは私にとっての問題でした!アプリをアンインストールすることで問題は解決しました。このES File Explorerがインストールされたとき、onStart() -> onResume() -> onPause() -> onResume() ..が問題でした。 onResume()は2'ceと呼ばれていました。

0
Pramod P K

その質問をご覧ください。 Nexus 5がスリープモードになると、アクティビティのライフサイクルがバグになります リードを見つける必要があります

私もこの問題に直面しました。これはフラグメントのためです。アクティビティにあるフラグメントの数onResume()はその回数を呼び出します。を克服するためにSharedPrefrencesのフラグ変数を使用しました

0
Sanju Baghla