2011-09-08 49 views
19

我正在編寫一個在固定時間顯示活動的應用程序。爲什麼在onCreate後立即調用onPause方法

我啓動活動從與這樣的代碼的服務:

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

不幸的是,的onPause()方法的onCreate之後立即調用。所以我的聲音信息立即停止。

但是,如果活動在屏幕未鎖定時開始,則在onCreate()之後不立即調用onPasue()。即使我評論了所有的「getWindow()。addFlags()」字符串,onCause()也會在onCreate()後被調用,當屏幕被鎖定時。

問題是爲什麼在onCreate之後立即調用onPause? 當用戶按下後退按鈕時,如何區分onPause()方法的立即調用和onPause()的調用?

以下是活動的代碼。我使用MVP模式,所以主代碼在演示者中。 但即使我評論所有演示者的電話(就像我在本例中完成的),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)); 
    } 

} 
+0

請顯示您在onPause()調用的整個代碼。 – user370305

+0

user370305,看到兩個最後一個帖子 – Andrey

+0

這就是爲什麼我告訴你顯示你的活動代碼 – user370305

回答

1

開始一個意圖,檢查用戶是否正在退出並將其綁定到退出按鈕。 我仍然不能確定你想要什麼作爲代碼是不完整的

+0

但是如果其他活動將在前面的情況下呢?有沒有可能跟蹤這種情況? – Andrey

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

但是如果其他活動在前面,情況如何?有沒有可能跟蹤這種情況? – Andrey

+0

首頁按鈕? – mehmet6parmak

4

以下是我想發生,則:您的服務創建你的活動,你的活動做幾件事情,如喚醒屏幕,解聘鑰匙。但這並不是即時的,這意味着鍵控保護活動在被解僱之前可能會被喚醒,從而暫時暫停你的活動。

我想你應該是什麼這樣的:http://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/

處理使用意圖吧。你意識到屏幕處於打開狀態,意圖屏幕關閉。

週期會像,我認爲:

  • 您將創建活動
  • 您的活動會去的onPause試圖解僱鍵盤鎖和調整一些東西
  • 你活動將再次喚醒
  • 您的活動將接受在屏幕上意圖

這意味着:當上暫停被調用,屏幕關閉!含義:你只需要一個標誌,如果這個標誌表示屏幕仍然關閉,你就不會暫停音樂。

這有點髒,但應該完美。

+0

儘管我評論了所有的「getWindow()。addFlags()」字符串,但onCause()在onCreate()時會在屏幕鎖定時調用onPause()。解除關鍵守衛並不會暫停我的活動。它確實有其他人。 – Andrey

+0

這可能只是屏幕關閉的事實。不是真正的關鍵保護。屏幕關閉=已創建但未顯示的活動,因此暫停。但是,在創建和暫停之後,循環繼續,並且讀取標誌「喚醒屏幕」,並且活動醒來。對於用戶來說,它是無意義的,但仍然... – Redwarp

5

我發現了我的問題的解決方案。

OnCrate之後調用onPause的原因是ActivityManager。 在日誌中我發現immendiately的onCreate後線:

  1. 的onCreate()
  2. 在onStart()
  3. 的onResume: 「爲HistoryRecord活動暫停超時」 所以,接下來的事件在我的活動happend對於HistoryRecord
  4. 的onPause()
  5. 的onResume(()
  6. 活動暫停超時)

我不知道如何防止「HistoryRecord的活動暫停超時」,但我改變了我的應用程序,它在onResume()中啓動聲音消息。即使它在onPause()中停止,它仍會在onResume()中再次啓動。

+0

另外,如果在你的'onCreate()'或'onStart()'或'onResume()'你開始*任何其他活動(即使是非視覺的作爲'TextToSpeech.Engine.ACTION_CHECK_TTS_DATA'),您的活動***將*暫停**。 – ateiob

4

我解決我的問題通過測試wheter屏幕開啓或關閉時使用此代碼:

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

因此上述碼N的onPause方法如果屏幕上只是做。當屏幕打開並調用onPause時,PowerManager的isScreenOn方法返回false。

+0

非常感謝。 當我的設備從睡夢中醒來時,我也遇到了「怪異的生命週期」的問題。感謝你,它現在正在工作。 但我真的不明白爲什麼生命週期是這樣的.. – AndyB

0

我從另一篇文章中得到線索,發現這是因爲ES文件資源管理器。 Why does onResume() seem to be called twice?

只要我強制停止「ES文件瀏覽器

(對於我來說,這只是如果應用程序被打開安裝後第一次或工作室建發生),這打嗝行爲沒有更長的時間。在嘗試了很多其他建議的解決方案之後,非常沮喪。

相關問題