如何正确关闭Landscape VideoView Activity?

时间:2011-10-26 22:20:11

标签: android android-videoview

在我的应用程序中,我有一个活动以横向模式播放http直播视频。

我的AndroidManifest.xml:

<activity android:name=".MediaPlayerActivity"
    android:label="@string/menu_player"
    android:launchMode="singleInstance"
    android:screenOrientation="landscape">
</activity>

我的活动布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  android:orientation="vertical"
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent"
  android:background="@color/black">

  <VideoView android:id="@+id/myVideoView"
    android:layout_height="fill_parent" 
    android:layout_width="fill_parent" 
    android:layout_gravity="center_horizontal" 
    android:layout_alignParentTop="true" 
    android:layout_alignParentRight="true" 
    android:layout_alignParentBottom="true" 
    android:layout_alignParentLeft="true"/>

</LinearLayout>

问题是我每次关闭此活动时(通过单击后退按钮),它会一直旋转到纵向模式(时间很快,但实际上可以在返回上一个活动之前看到效果),然后再关闭。我该如何解决这个恼人的问题?

使用更多信息进行更新
这种令人烦恼的行为只发生如果前一个活动处于纵向模式,如果前一个活动是横向,那就很好了。对我而言,当使用不同的screenOrientation设置淡入/淡出活动时,它看起来与Android框架有关。

更新原因
经过谷歌API的深入阅读后,我想我找到了造成这种令人讨厌的行为的原因,请查看here

  

除非您另行指定,否则配置更改(例如屏幕方向,语言,输入设备等的更改)将导致您的当前活动被破坏,通过onPause(),onStop的正常活动生命周期过程( )和onDestroy()视情况而定。如果活动位于前台或对用户可见,则在该实例中调用onDestroy()后,将创建活动的新实例,以及上一个实例从onSaveInstanceState(Bundle)生成的任何savedInstanceState。

所以当单击后退按钮时幕后发生的事情:currnet VideoView活动(风景)被破坏,由于screenOrientation配置已更改而创建了一个新的VideoView活动(肖像),并且会立即失效(您可以看到效果)在屏幕上),显示堆栈中的最后一个活动。这也解释了为什么如果最后一个活动具有相同的screenOrientation设置,这种恼人的行为就会消失。

我仍在试图弄清楚如何因配置更改而绕过此活动娱乐。正如API中所述,覆盖 然而,onConfigurationChanged(Configuration),因为我在xml中明确定义了screenOrientation,所以没有调用onConfigurationChanged(),之前已经讨论过很多类似的SO,比如this one

请提供正确方向的答案。

谢谢,
ÿ

5 个答案:

答案 0 :(得分:17)

尝试在您的活动的suspend()resume()stopPlayback()方法中添加对VideoView的onPause()onResume()onDestroy()的调用:

@Override
protected void onResume() {
    mVideoView.resume();
    super.onResume();
}

@Override
protected void onPause() {
    mVideoView.suspend();
    super.onPause();
}

@Override
protected void onDestroy() {
    mVideoView.stopPlayback();
    super.onDestroy();
}

VideoView类的实现因设备而异(并且类本身为very sparsely documented),但AOSP的Gallery3D代码确实调用了MovieView activity lifecycle methods中的上述方法,所以希望大多数设备都应该至少在这种情况下让自己看起来很好。

如果它仍然看起来很糟糕,您可能希望覆盖活动中的onBackPressed(),以隐藏VideoView或类似的黑客来隐藏恼人的行为:)

答案 1 :(得分:2)

由于如果您关闭一个活动并不总是重新创建活动,它可能不会始终执行您的清单代码,我很难确定这一点。

但您可以尝试的是在onResume中手动设置方向:

@Override
protected void onResume()
{
   setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
   super.onResume();
}

this有更多内容。

答案 2 :(得分:1)

我相信,一个简单的解决方案是在视频活动中添加一个字段:

boolean isClosing = false;

isClosing设置为true中的onDestroy,或者更好地设置在onBackPressed中(在致电finish()之前)

现在,我认为您已设置onConfigurationChanged以捕捉方向更改。

所以,在onConfigurationChangedif(!isClosing)

封装它
@Override
public void onConfigurationChanged(Configuration newConfig) 
{
  if(!isClosing){
      //YOUR OLD CODE
  }
}

答案 3 :(得分:0)

我建议您使用完全不同的横向和纵向模式布局,因为您可以使用不同的颜色。

我也会推荐API文档:http://developer.android.com/guide/topics/manifest/activity-element.html#screen(特别是关于处理savedBundle的部分)

答案 4 :(得分:0)

只有在清单文件中的活动中添加android:configChanges =“orientation”时,才会调用onConfigurationChanged。

这告诉系统您要手动处理方向更改,如果您还有android:screenOrientation =“landscape”,您还告诉系统该活动应以横向模式显示(它们应该一起工作到给你你想要的东西)