2013-04-16 49 views
36

基本上,這是我在做什麼爲什麼我的onResume被調用兩次?

1)設置AlarmManager從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執行廣播接收器(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)有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的時候了。我注意到這隻發生在屏幕被標誌打開時。有誰知道爲什麼發生這種情況?有什麼辦法可以防止這種行爲?

+0

我用過的標誌變量你的活動是否強制像肖像或風景的特定方向? – twaddington

+0

screenOrientation在清單中爲MyActivity設置爲縱向。 –

回答

5

我不確定發生了什麼,但我懷疑您的活動正在重新啓動,因爲設置屏幕處於系統視爲配置更改的狀態。您可以嘗試將每次調用的配置記錄到onResume以查看是否發生了這種情況,如果是這樣,實際上發生了什麼變化。然後,您可以修改清單,告訴系統您的活動將自行處理更改。

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

它看起來不像兩個onResumes之間有任何配置更改。 –

+0

@HyyT - 系統是否將任何內容放入日誌文件中,以指示發生了什麼? –

+0

我唯一能看到的是ActivityManager只會嘗試顯示Activity,並且PowerManagerService只能在onPause之後從睡眠中醒來。有沒有一種方法可以在onPause之前強制執行此操作? –

26

以防萬一別人運行到這一點,我似乎當我通過XML佈局膨脹活動的內部片段只注意到此行爲。我不知道這種行爲也與片段的兼容性庫版本(我使用android.app.Fragment)

看來活動將調用Activity#onResume一次調用Fragment#onResume任何附加片段之前,再發生將再次撥打Activity#onResume

  1. 活動:的onCreate
  2. 片段:onAttach
  3. 活動:onAttachFragments
  4. 片段:的onCreate
  5. 的活動:在onStart
  6. 活動:的onResume
  7. 片段:的onResume
  8. 活性: onResume
+5

想法如何克服這一點? – Shai

0

我也遇到了這個onresume-onpause-onresume序列(在4.1.2及更高版本上,但我沒有在2.3上遇到這個)。我的問題與wakelock處理有關:我不小心忘了釋放喚醒鎖並重新獲取,導致錯誤消息「WakeLock在仍然保留的情況下完成」。此問題導致onResume在onResume之後立即被調用並導致錯誤行爲。

我的建議是:檢查日誌中的錯誤,這些可能與此問題有關。

另一個提示:打開屏幕可能比簡單地使用窗口標誌更麻煩一點。你可能想在這裏檢查這個答案 - 它建議你設置一個接收器來檢查屏幕是否已經打開並且僅在以下時間啓動期望的活動:https://stackoverflow.com/a/16346369/875442

0

似乎從支持庫中使用Activity保存自動恢復實例。因此,只有你的工作,如果savedInstanceStatenull

2

我也有類似的問題,我的問題是,在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 
} 

希望它有幫助。

+0

您通過此評論節省了我很多時間。 TY! – Dani

+5

這並不能解決問題。人們如何能夠真正地提高這種無意義? – Johny19

0

我剛碰到這個,看起來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(),它只能調用一次。

5

我正在研究這一段時間,因爲在互聯網上沒有任何關於這種奇怪的行爲。我沒有辦法解決如何克服這種黑暗行爲,但是當它發生時我發現了一個確切的場景。

onPause-onResume-onPause-onResume只是每次發生,當應用程序安裝後第一次啓動。您可以通過在代碼中進行任何更改並重新運行(其中包括重新編譯)您的IDE中的應用程序來簡單地調用此行爲。

無論你是否使用AppCompat庫。我已經測試了兩種情況和行爲。

注意:測試Android棉花糖。

我從this thread about fragment and activity lifecycle借來的代碼,這裏是(只是複製,粘貼,在清單申報活動和運行林中運行):

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

} 
+0

我有完全相同的問題,使用三星銀河注4 ..你有沒有發現任何工作? – tsiro

+0

我還沒有找到任何解決方法。我已經停止在'onResume'和'onPause'中使用易受攻擊的操作(例如啓動線程等)。我已經將它們移到了「onStart」和「onStop」。 – matusalem

+0

我今天做得完全一樣...... – tsiro

8

如果您ES文件瀏覽器,強行停止它。不知何故,它們會中斷你的應用程序的生命週期。

我的問題是由於onResume被造成兩次是因爲onPause在創建活動後以某種方式被調用,有些事情正在中斷我的應用程序。

而且這隻發生在第一次打開後安裝後或打開。

我從另一篇文章中得到了CLUE,發現這是因爲ES文件瀏覽器。 Why does onResume() seem to be called twice?

只要我'強行停止'ES文件資源管理器,這種打嗝行爲不再發生......嘗試這麼多其他建議的解決方案後知道非常沮喪。

+1

可能是因爲ES Explorer在任何應用程序啓動時創建一個覆蓋來收集分析數據。這實質上會觸發焦點更改,這可能會導致重複的暫停和恢復觸發器 – anandbibek

2

我也有類似的問題。 我的情況是下 CurrentActivity延伸MainActivity CurrentFragment延伸MainFragment

我打開CurrentActivity意圖爲一般。在onCreate CurrentAcitivity我正在替換CurrentFragment。

生命週期是: 1的onResume MainActivity 2的onResume CurrentActivity 3的onResume MainFragment 4的onResume CurrentFragment

所謂的onPause自動,之後再

  1. 的onResume MainActivity
  2. 當前活動
  3. 的onResume CurrentFragment

我決定重新測試一切,幾個小時花在試圖和播放後,我發現根本問題。 在MainFragment onStart中,我每次都調用startActivityForResult(在我的例子中是用於打開Wifi的android彈出窗口),這是在MainFragment上調用onPause。我們所有人都知道onPause之後是onResume。

所以它不是Android的錯誤,這是:-)

快樂的生命週期僅調試運行雷!

0

基本上很多東西都可以觸發這個。一些恢復失去重點的進程可以做到這一點。一些應用程序也會導致它發生。唯一的辦法是阻止雙重跑。請注意,這也會導致錯誤的暫停,以便採取措施。

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

這是防止這種事情的可靠方法。它會阻止雙重恢復。但是,它也會阻止兩個保存內存的簡歷。所以如果你失去了重點,並且不需要重建你的東西​​。它也會阻止它。這可能是一個明顯的好處,因爲如果你使用簡歷來控制焦點的一些變化,你只需要確實在乎你是否因爲焦點而重建那些東西。由於預繪製偵聽器只能由一個線程調用,並且必須按順序調用它們,因此此處的代碼只能運行一次。直到正確地銷燬整個活動並將resumeblock恢復爲false。

0

我還面臨這個問題,這是因爲片段.. 你在活動onResume()中的片段數將調用該次數。克服我在SharedPrefrences

相關問題