Почему метод onPause вызывается сразу после onCreate - PullRequest
19 голосов
/ 08 сентября 2011

Я пишу приложение, которое показывает активность в фиксированное время.

Я запускаю активность из сервиса с таким кодом:

intent.setClass(context, FakeAction.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);

в методе onCreate FakeAction, который мне требуетсявключить устройство и запустить звуковое сообщение:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

В onCreate много кода для отображения информации на экране и запуска звукового сообщения.

Вот метод onPause:

@Override
protected void onPause()
{
    Log.i(TAG, "onPause");

    //Stop mediaPlayer
    if(mp != null)
    {
        if(mp.isPlaying())mp.stop();
        mp.release();
        mp = null;
    }

    //Restore volume
    if(audioManager != null)
    {
        audioManager.setStreamVolume(AudioManager.STREAM_ALARM, savedVolume, 0);
    }

    //Stop minute timer
    handler.removeCallbacks(minuteReceiver);

    super.onPause();
}

К сожалению, метод onPause () вызывается сразу после onCreate.Поэтому мое звуковое сообщение немедленно останавливается.

Но если действие начинается, когда экран не заблокирован, то onPasue () не вызывается сразу после onCreate ();

Даже если я комментируювсе строки "getWindow (). addFlags ()" onPause () вызывается после onCreate (), когда экран заблокирован.

Вопрос в том, почему onPause вызывается сразу после onCreate?Как я могу различить немедленный вызов метода onPause () и вызов onPause (), когда пользователь нажимает кнопку возврата?

Ниже приведен код действия.Я использую шаблон MVP, поэтому основной код находится в Presenter.Но даже если я прокомментирую все вызовы докладчика (как я это сделал в этом примере), onPause () вызывается сразу после onCreate ()

Может ли быть чувство, что я запускаю действие в AsyncTask?AsyncTask запускается из службы.Служба останавливается после AsyncTask, если завершена.

public class FakeAction extends RoboActivity
                            implements 
                            View.OnClickListener
                            ,AlarmAction
{
    private static final String TAG = "TA FakeAction";

    @InjectView(R.id.aa_btn_Stop)       Button btnStop;
    @InjectView(R.id.aa_btn_Snooze)     Button btnSnooze;
    @InjectView(R.id.aa_tv_CurTime)     TextView tvCurTime;
    @InjectView(R.id.aa_tv_CurDate)     TextView tvCurDate;
    @InjectView(R.id.aa_tv_AlarmName)   TextView tvAlarmName;

    @Inject public AlarmActionPresenter presenter;

    private Exception   ex;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        Log.i(TAG, "onCreate");

        super.onCreate(savedInstanceState);

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

        setContentView(R.layout.alarm_action);

        try
        {
            //presenter.onCreate(this);
        }
        catch(Exception ex)
        {
            this.ex = ex;
            Log.e(TAG, "onCreate",  ex);
        }

        btnStop.setOnClickListener(this);
        btnSnooze.setOnClickListener(this);


    }

    @Override
    protected void onPause()
    {
        Log.i(TAG, "onPause");

        //presenter.onPause();

        super.onPause();
    }

    @Override
    public void onClick(View v)
    {
        Log.i(TAG, "onClick");

        //presenter.onClick(v.getId());

    }

    @Override
    public Bundle getIntentBundle()
    {
        return getIntent().getExtras();
    }

    @Override
    public void setAlarmName(String alarmName)
    {
        tvAlarmName.setText(alarmName);
    }

    @Override
    public String getAlarmName()
    {
        return tvAlarmName.getText().toString();
    }

    @Override
    public void setCurTime(String curTime)
    {
        tvCurTime.setText(curTime);
    }

    @Override
    public String getCurTime()
    {
        return tvCurTime.getText().toString();
    }

    @Override
    public void setCurDate(String curDate)
    {
        tvCurDate.setText(curDate);
    }

    @Override
    public String getCurDate()
    {
        return tvCurDate.getText().toString();
    }



    @Override
    public IAssetFileDescriptorMockable openFd(String assetName) throws IOException
    {
        Log.i(TAG, "openFd");
        return new AssetFileDescriptorMockable(getAssets().openFd(assetName));
    }

}

Ответы [ 6 ]

5 голосов
/ 11 сентября 2011

Я нашел решение своей проблемы.

Причиной, по которой onPause вызывается после onCreate, является ActivityManager. В журнале я нашел строку сразу после onCreate: «Тайм-аут паузы активности для HistoryRecord» Итак, в моей Деятельности произошли следующие события:

  1. OnCreate ()
  2. OnStart ()
  3. onResume ()
  4. Тайм-аут приостановки активности для HistoryRecord
  5. OnPause ()
  6. onResume ()

Я не знаю, как предотвратить «Тайм-аут приостановки активности для HistoryRecord», но я изменил свое приложение, чтобы оно запускало звуковое сообщение в onResume (). Даже если он остановлен в onPause (), он снова запускается в следующем onResume ().

4 голосов
/ 08 сентября 2011

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

Я думаю, что вам следует сделать следующее: http://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/

Справиться с этим с помощью намерения.Вы ловите намерение, говоря, что экран включен, и намерение отключить экран.

Цикл будет работать так, я думаю:

  • Вы создадите свойзадание
  • Ваша активность будет продолжаться. Приостановите работу, пытаясь закрыть клавиатуру и настроив несколько вещей.
  • Ваша активность снова проснется
  • Ваша активность получит экран по назначению

Это означает, что при вызове onPause экран выключен!Значение: вам просто нужен флаг, и если этот флаг говорит, что экран все еще выключен, вы не приостанавливаете музыку.

Это немного грязно, но должно работать отлично.

3 голосов
/ 27 декабря 2012

Я решил свою проблему, протестировав, включен или выключен экран, с помощью этого кода:

PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);  
if (!powerManager.isScreenOn()){
   return;
}

Таким образом, метод кода n onPause выполняется только при включенном экране. Когда экран включается и вызывается onPause, метод isScreenOn в PowerManager возвращает false.

1 голос
/ 08 сентября 2011

Начните намерение, которое проверит, выходит ли пользователь, и свяжите это с вашей кнопкой выхода.Я все еще не уверен, что вы хотите, так как код неполон

0 голосов
/ 02 августа 2016

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

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

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

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

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

0 голосов
/ 08 сентября 2011
You can distinguish onPause() call between Acticity itself and back button press.

onBackPressed(){
// set isBackPressed = true;
}

onPause(){
if(isBackPressed ){
// exit due to back pressed.
}else{
// normal exit.
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...