如何判断Froyo中何时发生配置更改?

时间:2011-11-29 17:19:56

标签: android

在我的应用中,我希望播放媒体文件,并在用户旋转屏幕时继续播放(销毁活动),但如果用户移动到其他活动或其他活动出现,我希望它停止播放在这一个,他们按下后退按钮,无论如何。

我相信在Honeycomb中有一个API,但我需要一些适用于Android 2.2的东西。

我宁愿不使用onConfigurationChanged自己处理所有的配置更改 - 这听起来像是很多工作和潜在的错误 - 而onRetainNonConfigurationInstance()的问题是它在onStop fires之后才会运行 - - 如果合适,onPause将是暂停媒体的合理位置。

在onPause中,是否有办法判断Activity是否因配置更改而暂停,而不是其他原因?

5 个答案:

答案 0 :(得分: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 :(得分:7)

在Honeycomb之前,接受答案中提到的onRetainNonConfigurationInstance()是最好的方法。

从Honeycomb开始,这已被弃用,但有一种更简单的方法:在您isChangingConfigurations() / onPause() / onStop()的任何一期中调用onDestroy()

最后,如果使用支持库FragmentActivity( 在前Honeycomb上,onRetainNonConfigurationInstance()被声明为final,但您可以覆盖onRetainCustomNonConfigurationInstance()而不是相同的效果。

答案 2 :(得分: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()中的值(原始值)进行比较,那么您就知道它因屏幕旋转而关闭的活动。

答案 3 :(得分:0)

您可以尝试侦听ACTION_CONFIGURATION_CHANGED意图并设置一个内部标志,指示暂停来自配置更改。

我不确定您是否会及时收到意图,或者您将保证它会及时到达,因为它可能是异步的。可能值得一试。

答案 4 :(得分:0)

如果适用于您的情况,您也可以尝试使用View#onConfigurationChanged(例如,您有媒体播放器的视图并在视图中引用它)。