为什么我的onResume被调用两次?

时间:2013-04-16 00:19:41

标签: java android android-activity android-lifecycle

基本上,这就是我正在做的事情

1)设置AlarmManager以执行BroadcastReceiver(BCR)

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,请启用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。我注意到这只发生在标志打开被筛选时。有谁知道为什么会这样?有什么办法可以防止这种行为吗?

19 个答案:

答案 0 :(得分:28)

以防其他人遇到这种情况,我似乎只在通过XML布局将活动内的片段膨胀时才注意到这种行为。我不知道这种行为是否也发生在Fragments的兼容性库版本中(我使用的是android.app.Fragment)

在将Activity#onResume调用任何已添加的片段之前,该活动似乎会调用Fragment#onResume一次,然后再次调用Activity#onResume

  1. 的活动:的onCreate
  2. 片段:onAttach
  3. 的活动:onAttachFragments
  4. 片段:的onCreate
  5. 活动:onStart
  6. 活动:onResume
  7. 片段:onResume
  8. 活动:onResume

答案 1 :(得分:16)

如果你有ES File Explorer,那么强制停止。不知何故,他们会中断你的应用程序的生命周期(评论提示某种覆盖)

我的onResume被引发两次的问题是因为onPause在创建活动后以某种方式被调用。某些内容正在中断我的应用。

在安装后第一次打开或从工作室构建后发生。

我从另一篇文章中得到线索,发现这是因为ES文件资源管理器。 Why does onResume() seem to be called twice?

一旦我强制停止ES文件资源管理器,这种打嗝行为就不再发生......在尝试了许多其他提议的解决方案之后,知道它是令人沮丧的。所以要注意任何其他中断这样的应用程序。

答案 2 :(得分:7)

我正在研究这个问题一段时间,因为在互联网上没有提到这种奇怪的行为。我没有解决方法如何克服这种黑暗行为,但我确实找到了确实发生的确切情况。

每当app在安装后第一次启动时,

onPause-onResume-onPause-onResume就会发生。您可以通过对代码进行任何更改并从IDE重新运行(包括重新编译)应用程序来调用此行为。

无论您是否使用AppCompat库。我已经测试了这两种情况和行为继续进行。

注意:在Android Marshmallow上测试。

我借用了this thread about fragment and activity lifecycle中的代码,这里是(只需复制,粘贴,在清单中声明活动并运行Forest运行):

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()");
        }
    }

}

答案 3 :(得分:6)

如果您每次尝试请求权限都会导致此类问题,请检查您是否已授予他们

requestPermissions会导致它:

onCreate
onStart
onResume
onPause
onResume

答案 4 :(得分:5)

我不确定发生了什么,但我怀疑您的活动正在重新启动,因为设置屏幕会被系统视为配置更改。您可以尝试在每次调用onResume时记录配置,看看是否正在发生这种情况,如果是,那么实际发生了什么变化。然后,您可以修改清单,告诉系统您的活动将自行处理更改。

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

答案 5 :(得分:2)

我有类似的问题。 我的情况是下一个 CurrentActivity 扩展 MainActivity CurrentFragment 扩展 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
  5. 我决定重新测试所有内容,经过几个小时的尝试和玩耍后,我发现了root问题。 在MainFragment onStart中,我每次调用startActivityForResult(在我的情况下是用于打开Wifi的android弹出窗口),这是在MainFragment上调用onPause。我们所有人都知道onPause接下来是onResume。

    所以它不是Android的bug,它只是我的:-)

    快乐的生命周期调整!

答案 6 :(得分:2)

我有一个类似的问题,我的问题是在onCreate()方法中,我在做:

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

我打电话给&#34;超级。&#34;两次触发onResume()。在我将其更改为:

后,它按预期工作
@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.friends);  <-- 'super.' removed
}

希望它有所帮助。

答案 7 :(得分:0)

我刚刚遇到这个问题,似乎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()会被触发两次,但当我删除requestWindowFeature()时,它只会被调用一次。

答案 8 :(得分:0)

我想你应该看一下这个问题: Nexus 5 going to sleep mode makes activity life cycle buggy 你应该找到线索

答案 9 :(得分:0)

似乎使用支持库中的Activity会自动保存和恢复实例。因此,只有在savedInstanceStatenull时才能开展工作。

答案 10 :(得分:0)

基本上很多东西都可以触发这个。一些失去焦点的恢复过程可以做到。一些应用程序也会导致它发生。应对的唯一方法是阻止双重运行。请注意,这也会有一个错误的暂停,以便做好准备。

    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;
            }
        });
    }

这是防止此类事情的可靠方法。它将阻止双重简历。但是,它还会阻止两个保留内存的简历。所以,如果你失去了焦点,并且不需要重建你的东西​​。它也会阻止它。这可能是一个明显的好处,因为如果您使用简历来控制焦点上的某些更改,那么实际上只关心您是否因为焦点需要重建这些内容。由于预绘制侦听器只能由一个线程调用,并且必须按顺序调用它们,因此此处的代码只运行一次。直到某些东西正确销毁整个活动并将resumeblock设置为false。

答案 11 :(得分:0)

我也遇到了这个问题,这是因为碎片.. 您在活动onResume()中拥有的片段数量会调用该次数。克服我在SharedPrefrences

中使用的标志变量

答案 12 :(得分:0)

我还遇到了这个onresume-onpause-onresume序列(在4.1.2及更高版本上,但我没有在2.3上遇到过这种情况)。我的问题与唤醒锁处理有关:我不小心忘记释放唤醒锁并重新获取它导致错误,并显示“WakeLock在保持时仍然完成”的消息。此问题导致在onResume之后立即调用onPause并导致错误行为。

我的建议是:检查日志中的错误,这些可能与此问题有关。

另一个提示:打开屏幕可能比简单地使用窗口标志更棘手。您可能需要在此处查看此答案 - 它建议您设置接收器以检查屏幕是否已打开并仅在以下情况后启动所需的活动:https://stackoverflow.com/a/16346369/875442

答案 13 :(得分:0)

如@TWL所说   ES File Explorer 对我来说是个问题! 卸载应用程序即可解决问题。 安装此 ES File Explorer 时,问题是onStart() -> onResume() -> onPause() -> onResume()..。 onResume()被称为2'ce。

答案 14 :(得分:0)

我有同样的问题。我的是在运行时编写此代码的

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

我只是将其放在清单中

android:screenOrientation="landscape"

两次调用onCreate和onResume不再有问题。

答案 15 :(得分:0)

我对这个问题没有足够的答案,所以我决定了。

从“我的笔记”中: “似乎该活动先运行onResume(),onPause(),然后再次运行onResume。最后一个运行的方法是onSizeChanged()。因此,一个好的做法是仅在执行onSizeChanged()方法之后启动线程。”

因此,您可以:记录每个运行的方法。确定最后运行的方法。确保您具有一个布尔值,该布尔值初始化为false,并且仅在最后一个方法运行后才更改为true。然后,一旦您检查布尔值是否正确,就可以启动所有线程操作。

-对于任何想知道的人:我使用的表面视图都有一个onSizeChanged()方法,该方法执行得最晚。

答案 16 :(得分:0)

我遇到了同样的问题,因为在UiMode的{​​{1}}中设置了onCreate()。更改主题会触发MainActivity重新娱乐,并两次致电activityonPause()

答案 17 :(得分:0)

您是否曾尝试在import pandas as pd df = pd.read_csv(filename, nrows=1000) 方法中调用getWindow().addFlags(...)之前先调用super.onCreate(savedInstanceState)

我有类似的问题。当我的onCreate看起来像这样时,onResume被呼叫了两次:

onCreate

将其更改为:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
    setContentView(R.layout.main);
    ...
}

...解决了问题。

答案 18 :(得分:0)

我确定这是在我的应用程序中发生的,直到我意识到自己已经种了两棵杰克·沃顿的树木,而onResume()才被记录了两次。