Почему мой 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()
, он вызывает только один раз.
Ответ 11
Думаю, вам стоит взглянуть на этот вопрос:
Nexus 5 переходит в спящий режим делает работу жизненным циклом багги
Вы должны найти выводы
Ответ 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.