为什么在onCreate之后立即调用onPause方法

时间:2011-09-08 08:34:46

标签: android

我正在编写一个在固定时间显示活动的应用程序。

我使用此类代码从服务开始活动:

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

在FakeAction的onCreate方法中我需要唤醒设备并启动声音消息:

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

不幸的是onCreate后立即调用onPause()方法。所以我的声音信息会立即停止。

但是如果在未锁定屏幕时启动活动,则在onCreate()之后不会立即调用onPasue();

即使我评论所有" getWindow()。addFlags()"字符串onCause()在onCreate()之后被调用,如果屏幕被锁定。

问题是为什么在onCreate之后立即调用onPause? 当用户按下后退按钮时,如何区分onPause()方法的立即调用和onPause()的调用?

以下是活动的代码。我使用MVP模式,因此,主要代码在演示者中。 但即使我评论所有演示者的调用(就像我在本例中所做的那样),onCreate()之后立即调用onPause()

我是否可以在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 个答案:

答案 0 :(得分:5)

我找到了解决问题的方法。

onCreate之后调用onPause的原因是ActivityManager。 在日志中我在onCreate之后找到了该行:“HistoryRecord的活动暂停超时” 所以,我的活动中发生了下一个事件:

  1. 的onCreate()
  2. 在onStart()
  3. 的onResume()
  4. HistoryRecord的活动暂停超时
  5. 的onPause()
  6. 的onResume()
  7. 我不知道如何阻止“HistoryRecord的活动暂停超时”但我更改了我的应用程序,因此它在onResume()中启动声音消息。即使它在onPause()中停止,它也会在下一个onResume()中再次启动。

答案 1 :(得分:4)

以下是我认为发生的事情:您的服务会创建您的活动,而您的活动会执行多项操作,例如唤醒屏幕并解除键盘锁定。但这不是即时的,这意味着关键保护活动可能在被解雇之前被唤醒,从而暂停你的活动。

我认为你应该这样做:http://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/

使用意图处理它。你抓住了屏幕打开的意图,以及屏幕关闭的意图。

这个循环会像那样工作,我想:

  • 您将创建活动
  • 您的活动将在尝试解除键盘锁并调整一些内容时继续执行
  • 您的活动将再次唤醒
  • 您的活动将按意图接收屏幕

这意味着:当调用onPause时,屏幕关闭!含义:你只需要一个标志,如果这个标志表示屏幕仍然关闭,你就不会暂停音乐。

它有点脏,但应该完美。

答案 2 :(得分:3)

我通过使用以下代码测试屏幕打开或关闭来解决我的问题:

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

因此只有在屏幕打开时才会执行代码n onPause方法。当屏幕打开并且调用onPause时,PowerManager的isScreenOn方法返回false。

答案 3 :(得分:1)

启动一个意图,检查用户是否退出并将其与退出按钮绑定。 由于代码不完整,我仍然不确定你想要什么

答案 4 :(得分:0)

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.
}
}

答案 5 :(得分:0)

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

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

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

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

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