2010-01-04 88 views
232

按下後退按鈕時,我希望我的應用程序進入停止狀態,而不是被破壞的狀態。覆蓋後退按鈕以充當主頁按鈕

在Android docs它指出:

...不是所有的活動具有以下行爲被壓回來時,他們被摧毀。當用戶開始播放音樂在音樂應用程序,然後按下BACK,應用覆蓋了正常的回行爲,防止被破壞的玩家活動,並繼續播放音樂,即使它的活動將不再可見

如何在我自己的應用程序中複製此功能?

我認爲必須有三種可能性......

  1. 捕獲後退按鈕按下(如下圖),然後調用任何方法(S)的home鍵調用。

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
        if ((keyCode == KeyEvent.KEYCODE_BACK)) { 
         Log.d(this.getClass().getName(), "back button pressed"); 
        } 
        return super.onKeyDown(keyCode, event); 
    } 
    
  2. 捕獲後退按鈕然後欺騙主頁按鈕按下。

  3. 捕獲後退按鈕按下,然後啓動主屏幕的活動,有效地將我的應用程序的活動進入停止狀態。

編輯: 我知道服務和正在使用的應用程序之一,它這個問題有關。這個問題具體是關於在按下後退按鈕時將活動置於停止狀態而非已銷燬狀態。

+0

看到了類似的回答http://stackoverflow.com/questions/5914040/onbackpressed-to-hide-not-destroy-activity/23759328#23759328 – Nepster 2014-05-20 12:06:51

回答

324

大多數情況下,您需要創建Service才能在後臺執行某些操作,而您可見的Activity只是簡單控制此Service。 (我確定音樂播放器以相同的方式工作,所以文檔中的示例似乎有點誤導)。如果是這種情況,那麼您的Activity可以像往常一樣finishService仍然會運行。

更簡單的方法是捕捉Back按鈕按壓和呼叫moveTaskToBack(true)如下:

// 2.0 and above 
@Override 
public void onBackPressed() { 
    moveTaskToBack(true); 
} 

// Before 2.0 
@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_BACK) { 
     moveTaskToBack(true); 
     return true; 
    } 
    return super.onKeyDown(keyCode, event); 
} 

我認爲優選的選擇應該是一個活動正常完成並且能夠重新本身例如如果需要,從服務中讀取當前狀態。但有時可以使用moveTaskToBack作爲快速替代品。

注意:如指出,由Dave低於Android 2.0的推出了新的onBackPressed方法,以及these recommendations如何處理後退按鈕。

+1

moveTaskToBack()表現爲所希望的工作。使用這種方法會有什麼缺點?有沒有這種情況下,這可能無法按預期工作? – bdls 2010-01-04 16:14:22

+1

在仔細閱讀文檔後,我認爲它應該可以正常工作。 (我最初認爲它適用於該活動,但實際上它說的是「包含此活動的任務」。)但是當然,您應該自己測試它。 :) – 2010-01-04 16:28:02

+0

謝謝Mirko,該方法似乎運作良好。如果您在稍後查看此問題的答案的底部給出更加突出的編輯方式,這可能會很酷 - 因爲那是我尋找的位! – bdls 2010-01-04 17:20:45

22

如果你想趕上後退按鈕看看this post on the Android Developer Blog。它涵蓋了在Android 2.0中執行此操作的更簡單的方法,以及爲在1.x和2.0上運行的應用程序執行此操作的最佳方法。

但是,如果您的活動已停止,它仍然可能會被殺死,具體取決於設備上的內存可用性。如果你想要一個沒有UI的進程運行,你應該創建一個ServiceThe documentation says the following about Services:

服務沒有可視用戶界面,而是在無限期的時間內在後臺運行。例如,服務可能會在用戶參加其他事務時播放背景音樂,或者可能通過網絡獲取數據或計算某些內容,並將結果提供給需要它的活動。

這些似乎適合您的要求。

17

嘗試覆蓋android.app.Activity類中定義的void onBackPressed()

+1

因爲android 2.0這是正確的覆蓋。 http://developer.android.com/sdk/android-2.0.html – jay 2011-09-29 19:54:42

+2

16 upvotes像這樣的答案... 2011是一個不同的時間... – GabrielOshiro 2016-06-28 15:26:55

13

如果它可以幫助別人,我有一個活動2佈局,我開始和關閉visibilty,試圖模仿一種page1> page2結構。如果他們在第2頁上並按下後退按鈕,我希望他們回到第1頁,如果他們按下了第1頁上的後退按鈕,它仍然可以正常工作。它非常基本的,但它的工作原理

@Override 
public void onBackPressed() { 
// check if page 2 is open 
    RelativeLayout page2layout = (RelativeLayout)findViewById(R.id.page2layout); 
    if(page2layout.getVisibility() == View.VISIBLE){ 
     togglePageLayout(); // my method to toggle the views 
     return; 
    }else{ 
     super.onBackPressed(); // allows standard use of backbutton for page 1 
    } 

} 

希望它可以幫助別人, 歡呼

-1

我使用@Mirko N. answser使用作出的新的自定義的EditText

public class EditViewCustom extends EditText { 

    Button cancelBtn; 
    RelativeLayout titleReleLayout; 
    public EditViewCustom(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    public EditViewCustom(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public EditViewCustom(Context context) { 
     super(context); 
    } 

    public void setViews(Button cancelBtn,RelativeLayout titleReleLayout){ 
     this.cancelBtn = cancelBtn; 
     this.titleReleLayout = titleReleLayout; 
    } 

    @Override 
    public boolean onKeyPreIme(int keyCode, KeyEvent event) { 
     if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { 
      Log.d("KEYCODE_BACK","KEYCODE_BACK"); 
      cancelBtn.setVisibility(View.GONE); 
      this.setFocusableInTouchMode(false); 
      this.setFocusable(false); 
      titleReleLayout.setVisibility(View.VISIBLE); 

      return super.onKeyPreIme(keyCode, event); 
      } 

     return super.onKeyPreIme(keyCode, event); 
    } 

} 

然後從設置你的數據活動

searchEditView.setViews(cancelBtn, titleRelativeLayout); 

謝謝。

42

使用下面的代碼:

public void onBackPressed() {  
    Intent intent = new Intent(); 
    intent.setAction(Intent.ACTION_MAIN); 
    intent.addCategory(Intent.CATEGORY_HOME); 
    startActivity(intent); 
} 
0

更妙的是,怎麼樣OnPause()

古稱當活動進入後臺活動週期的一部分,但還沒有(尚未)殺害。與onResume()的對應部分。

當活動B在活動A前面啓動時,此回調將在A上調用.B將不會創建,直到A的onPause()返回,所以請確保enter code here在此處不做任何冗長的操作。

此回調函數主要用於保存活動正在編輯的任何持久狀態,並確保沒有足夠的資源來啓動新活動而沒有先殺死該活動,則不會丟失任何內容。

這也是一個很好的地方,可以做停止動畫和其他消耗大量CPU的東西,以便儘可能快地切換到下一個活動,或關閉獨佔訪問等資源作爲相機。

8

工作實例..

製作肯定不叫super.onBackPressed();

@Override 
public void onBackPressed() { 
    Log.d("CDA", "onBackPressed Called"); 
    Intent setIntent = new Intent(Intent.ACTION_MAIN); 
    setIntent.addCategory(Intent.CATEGORY_HOME); 
    setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    startActivity(setIntent); 
} 

通過這種方式,您的後退按鈕就像Home按鈕一樣。它不會完成你的活動,但它採取的背景

第二種方式是使用Android 2.0後打電話到moveTaskToBack(true);onBackPressed,並一定要刪除super.onBackPressed

0

覆蓋onBackPressed()。 如

@Override 
public void onBackPressed() { 
    moveTaskToBack(true); 
}