Почему мой onResume называется дважды?

В принципе, это то, что я делаю

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) Запустите MyActivity из BCR

@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. Я замечаю, что это происходит только тогда, когда экранирование включается флагами. кто-нибудь знает, почему это произошло? Можно ли предотвратить это поведение?

Ответ 1

На всякий случай, когда кто-то сталкивается с этим, я, похоже, замечаю это поведение только тогда, когда я раздуваю фрагменты внутри действия с помощью XML-макета. Я не знаю, происходит ли это также с версией библиотеки совместимости Fragments (я использую android.app.Fragment)

Кажется, что операция вызовет Activity#onResume один раз перед вызовом Fragment#onResume в любые добавленные фрагменты, а затем снова вызовет Activity#onResume.

  • Активность: OnCreate
  • Фрагмент: onAttach
  • Активность: onAttachFragments
  • Фрагмент: OnCreate
  • Деятельность: onStart
  • Активность: onResume
  • Фрагмент: onResume
  • Активность: onResume

Ответ 2

Если у вас есть ES File Explorer тогда FORCE STOP это. Так или иначе, они прерывают ваш жизненный цикл приложения (комментарии предлагают какой-то наложение).

Моя проблема с onResume вызвана дважды, потому что onPause как-то вызывался после того, как была создана активность. onPause то прерывало мое приложение.

И это происходит только после первого открытия после установки или из студии.

Я получил ключ от другого сообщения и узнал, что это связано с ES File Explorer. Почему onResume(), кажется, называется дважды?

Как только я заставляю остановить ES File Explorer, это поведение икоты больше не происходит... это разочаровывает, когда вы пытаетесь найти множество других предлагаемых решений. Поэтому будьте осторожны с другими прерывательными приложениями, такими как этот.

Ответ 3

Я об этом некоторое время разбирался, потому что в Интернете нет никаких упоминаний об этом странном поведении. У меня нет решения, как преодолеть это поведение с темной стороны, но я нашел точный сценарий, когда это происходит.

onPause-onResume-onPause-onResume просто происходит каждый раз, когда приложение запускается с первого раза после установки. Вы можете просто вызвать это поведение, выполнив любое изменение кода и повторное использование (которое включает перекомпиляцию) приложения из вашей среды разработки.

Независимо от того, используете ли вы AppCompat libs или нет. Я тестировал оба случая, и поведение продолжается.

Примечание. Протестировано на Android Marshmallow.

Я заимствовал код этого потока о жизненном цикле фрагментов и активности, и вот он (просто скопируйте, вставьте, объявите активность в манифесте и запустите Forest run):

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

}

Ответ 4

Я точно не знаю, что происходит, но я подозреваю, что ваша активность перезапускается, потому что установка экрана на экране рассматривается системой как изменение конфигурации. Вы можете попытаться выполнить регистрацию конфигурации при каждом вызове onResume, чтобы узнать, что происходит, и если да, то что на самом деле меняется. Затем вы можете изменить манифест, чтобы сообщить системе, что ваша деятельность будет обрабатывать изменение самостоятельно.

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

Ответ 5

если вы пробовали разрешения на запрос каждый раз, когда это может вызвать такие проблемы, просто проверьте, уже ли вы их предоставили

requestPermissions может вызвать это:

onCreate
onStart
onResume
onPause
onResume

Ответ 6

У меня была аналогичная проблема, и моя проблема заключалась в том, что в методе onCreate() я делал:

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

Мой звонок к "супер". запускал onResume() дважды. Он работал по назначению, после того как я изменил его на просто:

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

Надеюсь, что это поможет.

Ответ 7

У меня схожая проблема. Моя ситуация была следующей Текущая активность расширяет MainActivity CurrentFragment расширяет MainFragment

Я открывал CurrentActivity с намерением, как обычно. В onCreate CurrentAcitivity Я заменял CurrentFragment.

Жизненный цикл: 1. onResume MainActivity 2. onResume CurrentActivity 3. onResume MainFragment 4. onResume CurrentFragment

вызывается onPause автоматически, а после этого

  • onResume MainActivity
  • onResume CurrentActivity
  • onResume MainFragment
  • onResume CurrentFragment

Я решил повторить все, и после нескольких часов тратить и играть, я нашел корень проблемы. В MainFragment onStart я каждый раз вызывал startActivityForResult (в моем случае всплывающее окно Android для включения Wi-Fi), которое вызывало onPause на MainFragment. И все мы знаем, что после onPause next onResume.

Итак, это не ошибка Android, это только моя:-)

Счастливая отладка жизненного цикла!

Ответ 8

Я также столкнулся с этой последовательностью onresume-onpause-onresume (на 4.1.2 и выше, но это не произошло на 2.3). Моя проблема была связана с обработкой wakelock: я случайно забыл выпустить wakelock и снова вызвал ошибку, вызвав сообщение с сообщением "WakeLock финализировалось, пока все еще удерживается". Эта проблема привела к тому, что onPause вызывается сразу после onResume и приводит к ошибочному поведению.

Мое предложение: проверить наличие ошибок в журнале, это может быть связано с этой проблемой.

Еще один намек: включение экрана может быть немного сложнее, чем просто использовать флаги окон. Вы можете проверить этот ответ здесь - он предлагает вам настроить приемник, чтобы проверить, включен ли экран и запустить его только после: fooobar.com/questions/165082/...

Ответ 9

Кажется, что использование Activity из библиотеки поддержки сохраняет и восстанавливает экземпляр автоматически. Поэтому выполняйте свою работу, если savedInstanceState null.

Ответ 10

Я просто столкнулся с этим, и кажется, что 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(), он вызывает только один раз.

Ответ 12

В принципе, многие вещи могут вызвать это. Некоторые процессы возобновления, которые теряют фокус, могут это сделать. Несколько приложений вызовут это тоже. Единственный способ справиться - заблокировать двойную работу. Обратите внимание, что это также приведет к ошибочной паузе, сделанной для хорошей меры.

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

Это надежный способ предотвратить такие вещи. Он будет блокировать двойные резюме. Но он также блокирует два резюме, которые сохраняют память. Поэтому, если вы просто потеряли фокус, и вам не нужно перестраивать ваши вещи. Это тоже заблокирует. Что может быть полезно, потому что, если вы используете резюме для контроля над некоторыми изменениями в фокусе, вы действительно заботитесь только о том, нужно ли вам перестроить этот материал из-за фокуса. Поскольку прослушиватели предварительного рисования могут быть вызваны только одним потоком, и их необходимо вызвать последовательно, код здесь будет запускаться только один раз. Пока что-то не уничтожит всю активность и не вернет returnblock в false.

Ответ 13

Я также столкнулся с этой проблемой, это из-за фрагментов. количество фрагментов, которые у вас есть в активности onResume(), будет вызывать это количество раз. для преодоления я использовал переменные флага в SharedPrefrences

Ответ 14

как @TWL сказал ES File Explorer была проблема для меня! Деинсталляция приложения решила проблему. Когда этот ES файл был установлен, onStart() → onResume() → onPause() → onResume().. была проблема. onResume() называется 2'ce.

Ответ 15

У меня такая же проблема. Мой был для этого кода во время выполнения

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

Я просто выразился

android:screenOrientation="landscape"

больше не проблема о двойном вызове onCreate и onResume.