2011-11-29 55 views
10

在我的應用程序中,如果用戶旋轉屏幕(銷燬活動),我想要播放媒體文件並繼續播放,但如果用戶移動到其他活動或其他活動出現,我希望它停止播放這一個,他們按下後退按鈕,不管。如何知道Froyo中配置更改發生的時間?

我相信在Honeycomb中有一個這樣的API,但我需要一些能在Android 2.2中工作的東西。

我寧願不使用onConfigurationChanged來自己處理所有配置更改 - 這聽起來像很多工作和潛在的錯誤 - 而onRetainNonConfigurationInstance()的問題在於,它只有在onStop觸發後纔會運行 - 但如果合適,onPause將是暫停介質的合理位置。

在onPause中,有沒有一種方法可以判斷活動是否因配置更改而暫停而不是其他原因?

回答

9

您的解決方案至少存在一個潛在問題。

根據Android文檔:

一些設備配置可以在運行過程中改變(例如,屏幕取向,鍵盤可用性和語言)。當發生這種變化時,Android會重新啓動正在運行的Activity(onDestroy()被調用,然後是onCreate())。

測試旋轉變化只處理一種情況。由於這可能是配置更改的最常見原因,因此這是一個很好的解決方案。但是如果你可以處理所有的情況,現有的或添加到未來版本的Android中,而沒有自己處理配置的開銷呢?

更新爲使用onRetainNonConfigurationInstance。 Android的文件有這樣說的:

被系統調用,如破壞活動的一部分,由於配置的變化,當一個新的實例將立即爲新配置創建它是已知的。

還改變鏈super.onDestroy()停止媒體後發生,但不完全確定。猜猜這取決於停止媒體的意義,以及銷燬媒體可能會產生什麼效果。

private Boolean mConfigurationChange = false; 

public Object onRetainNonConfigurationInstance() { 
    mConfigurationChange = true; 
    return null; 
} 

public void onDestroy() { 
    if (!mConfigurationChange) { 
     // Code to stop media file goes here. 
    } 
    super.onDestroy(); 
}  
+1

一個有趣的想法,朱利安,謝謝你的詳細例子。一旦我將android:configChanges =「orientation」添加到清單中的相關Activity中,它就會生效,但不會如我所料。 onConfigurationChanged是否會觸發...但onPause/onStop/onDestroy永遠不會被調用。因此,這是解決「旋轉屏幕破壞活動」問題的一種方法,但不是以Google推薦的方式。雖然謝謝! –

+0

查看更新的答案。不涉及對manifest和onDestroy()仍然調用的更改。 –

+1

新的答案似乎工作! OnRetainNonConfigurationInstance會在onStop之後和onDestroy之前觸發,並且使用此代碼可以準確判斷onDestroy是否正在關閉配置更改。謝謝! –

0

您可以嘗試偵聽ACTION_CONFIGURATION_CHANGED意圖並設置一個內部標誌,指示暫停來自配置更改。

我不確定您是否會及時收到該意圖,或者您將得到保證,它會及時到達,因爲它可能是異步的。雖然可能值得一試。

2

我終於想出了自己的問題的答案!

public class MyActivity extends Activity { 

    Display display; 
    int originalRotation; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 
     originalRotation = display.getRotation(); 
    } 

    public boolean endingDueToConfigurationChanging() { 
    int newRotation = display.getRotation(); 
    return (newRotation != originalRotation); 
    } 
} 

Display.getRotation()旨在返回一個常量,指示設備是否偏離其自然旋轉的0,90,180或270度。但是,當設備旋轉時,該值在活動結束之前進行更新 - 實際上它早於onPause()更新!因此,如果您將onPause()(新值)與onCreate()(原始值)中的值進行比較,那麼您知道由於屏幕旋轉而導致它關閉的活動。

+0

什麼使用「endingDueToConfigurationChanging」?我想也許這是一些API Android調用,如果你返回false,它畢竟不會結束,但顯然它不是,我不能告訴你如何使用它。 – Michael

+0

那是五年以及幾家公司之前......恐怕我不知道。我猜我不小心遺漏了一些調用endingDueToConfigurationChanging的代碼。好吧。現在有更好的答案。 –

0

如果適用於您的情況(例如 - 您有媒體播放器的視圖並在視圖中對其進行引用),則還可以嘗試使用View#onConfigurationChanged

+0

感謝您的回答,iLate,但正如我在我原來的問題中所述,如果我使用onConfigurationChanged,那麼我將用自己的代碼替換Android的旋轉處理 - 這意味着我將不得不手動更改佈局等。這是一個很多工作要做,以實現我知道配置是否正在改變的簡單目標。 –

+0

我告訴你重寫View#onConfigurationChanged,而不是Activity#onConfigurationChanged。無論您在清單文件中指定了什麼內容,配置更改之後,您的活動都會被重新創建,然後在之前每次調用此方法。 – asenovm

+0

一個完整的例子可能會幫助我更好地理解。我認爲你建議在那裏做一個自定義View類並覆蓋onConfigurationChanged?除非我將android:configChanges =「orientation」添加到清單中的相關Activity,否則onPause/onStop/onDestroy永遠不會被調用。不過謝謝。 –

6

此前在接受的答案提到的蜂窩,onRetainNonConfigurationInstance()是做到這一點的最好辦法。

Honeycomb的開始,這是過時了,但有一個更簡單的方法:撥打isChangingConfigurations()相反,在任何你onPause()/onStop()/onDestroy()的。

最後,如果使用預蜂窩狀的支持庫FragmentActivity( android.support.v4.app.FragmentActivity),onRetainNonConfigurationInstance()聲明決賽,但是你可以重寫onRetainCustomNonConfigurationInstance()代替了同樣的效果。

相關問題