【问题标题】:How to close Landscape VideoView Activity properly?如何正确关闭 Landscape VideoView Activity?
【发布时间】:2011-10-26 22:20:11
【问题描述】:

在我的应用程序中,我有一个以横向模式播放 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 框架有关。

更新原因
在深入阅读了 Google 的 API 之后,我想我找到了导致这种烦人行为的原因,请查看 here

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

所以点击后退按钮时幕后发生了什么: currnet VideoView Activity(横向)被销毁,由于 screenOrientation 配置已更改,创建了一个新的 VideoView Activity(纵向),并立即销毁(您可以在其中看到效果在屏幕上),显示堆栈中的最后一个活动。这也解释了为什么如果最后一个活动具有相同的屏幕方向设置,这种烦人的行为就会消失。

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

请提供正确方向的答案。

谢谢,
是的

【问题讨论】:

  • 我不知道这是否正确 b/c 我没有遇到问题.. 您是否考虑过覆盖后退按钮并在按下时尝试完成()(至少这是第一个我会尝试)。
  • 刚刚试过,同样的行为,顺便说一句,我使用的是 Galaxy s2,我怀疑这与设备有关。

标签: android android-videoview


【解决方案1】:

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

@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 或一些类似的黑客来隐藏烦人的行为:)

【讨论】:

  • 工作就像一个魅力,虽然我还没有完全理解代码背后的魔力,但有时间我会进一步研究。谢谢:)
【解决方案2】:

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

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

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

this 有更多内容。

【讨论】:

  • 我不太明白你的意思。我没有看到覆盖 onResume 可以帮助解决这个问题的任何点。无论如何,我已经尝试了你的建议,同样的行为。
【解决方案3】:

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

boolean isClosing = false;

onDestroy 中将isClosing 设置为true,或者更好的是在onBackPressed 中(在调用finish() 之前)

现在,我猜你已经设置了onConfigurationChanged 来捕捉方向变化。

所以,在你的onConfigurationChanged 中用if(!isClosing) 封装它

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

【讨论】:

  • onConfigurationChanged() 不会被 xml 中明确定义的 screenOrientation 调用,我需要先解决这个问题。另外,从我的角度来看,问题与活动如何被销毁/完成/关闭无关,而是关于如何绕过/避免由于配置更改而重新创建活动。
  • 你能试试吗?只需添加onDestroyisClosing=true 并在onCreate 的顶部添加if(isClosing) finish()。我希望你明白。我知道这会产生一些其他问题,但请检查这是否能解决问题。
  • 我尝试了你的和约瑟夫的,他的答案对我有用,我在问题中描述的活动生命周期不太正确,有时间我会进一步研究。
【解决方案4】:

我推荐的横向和纵向模式可以使用完全不同的布局,因为你可以使用不同的方式。

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

【讨论】:

    【解决方案5】:

    只有在清单文件中将 android:configChanges="orientation" 添加到 Activity 时才会调用 onConfigurationChanged。

    这告诉系统你想要手动处理方向变化,如果你也有 android:screenOrientation="landscape",你也告诉系统活动应该以横向模式显示(它们应该一起工作以给你你想要的)

    【讨论】:

    • 是的,我可以理解 API。你只是再描述一次问题。如果您同时定义了 android:configChanges 和 android:screenOrientation,则不会调用 onConfigurationChanged()。在 SO 上搜索“onConfigurationChanged() not called”,您可以找到讨论此问题的线程页面。好吧,答案是不使用 android:screenOrientation,但是,这不是我的选择。
    • 对不起,您没有提到您已经在使用configChanges,并且我已经使用它来解决打开硬件键盘唤醒设备时的类似问题(导致设备被唤醒)当应用程序应该是纵向时,横向)。
    猜你喜欢
    • 2015-08-21
    • 1970-01-01
    • 2012-06-27
    • 2017-03-29
    • 2019-07-20
    • 2019-04-12
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多