Как правильно закрыть Пейзаж VideoView Activity? - PullRequest
9 голосов
/ 27 октября 2011

В моем приложении активен просмотр потокового видео в режиме реального времени.

Мой 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>

Проблема в том, что каждый раз, когда я закрываю это действие (нажав кнопку "Назад"), оно всегдаповерните в портретный режим (время очень скоро, но вы можете увидеть эффект на реальном устройстве, прежде чем вернуться к предыдущему действию) перед закрытием.Как я могу исправить эту раздражающую проблему?

Обновление с дополнительной информацией
Это раздражающее поведение произошло только в том случае, если предыдущее действие было в портретном режиме, если предыдущее - в альбомной ориентации, онопросто хорошо.Для меня это выглядит как что-то, связанное с платформой Android, когда появляются и исчезают действия с различными настройками экранной ориентации.

Обновление с указанием причины
После некоторого глубокого изучения API Google, я думаю, я нашел причину, которая вызывает это раздражающее поведение, проверьте здесь :

Если не указано иное, изменение конфигурации (например, изменение ориентации экрана, языка, устройств ввода и т. Д.) Приведет к разрушению вашей текущей активности, проходя обычный жизненный цикл активности onPause(), onStop () и onDestroy () в зависимости от ситуации.Если действие находилось на переднем плане или было видимым для пользователя, при вызове onDestroy () в этом экземпляре будет создан новый экземпляр действия, с каким бы параметром saveInstanceState был сгенерирован предыдущий экземпляр из onSaveInstanceState (Bundle).

Итак, что произошло за кулисами, когда нажата кнопка «Назад»: currnet Действия VideoView (ландшафт) разрушены, новое действие VideoView (портрет) создано из-за изменения конфигурации screenOrientation и немедленного уничтожения (там, где выможно увидеть эффекты на экране), отображается последняя активность в стеке.это также объясняет, почему это раздражающее поведение исчезло, если последнее действие имело те же настройки screenOrientation.

Я все еще пытаюсь выяснить, как обойти эту деятельность из-за изменения конфигурации.Как указано в API, переопределение onConfigurationChanged (Configuration), тем не менее, поскольку я явно определяю screenOrientation в xml, onConfigurationChanged () не вызывается, много подобных SO обсуждалось ранее, например, этот .

Пожалуйста, дайте ответ в правильном направлении.

Спасибо,
Y

Ответы [ 5 ]

17 голосов
/ 02 ноября 2011

Попробуйте добавить вызовы к VideoView suspend(), resume() и stopPlayback() в методах 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 варьируется от одного устройства к другому (и сам класс очень редко документирован ), но код Gallery3D из AOSP действительно вызывает вышеуказанные методы в его методах жизненного цикла действия MovieView , так что, надеюсь, большинство устройств по крайней мере должно выглядеть хорошо в этом сценарии.

Если он по-прежнему выглядит плохо, вы можете переопределить onBackPressed() в своей активности, чтобы скрыть VideoView или некоторые подобные хаки, чтобы скрыть раздражающее поведение:)

2 голосов
/ 29 октября 2011

Поскольку ваша деятельность не всегда воссоздается, если вы ее закрываете, она может не всегда выполнять ваш манифест-код, хотя я не уверен в этом.

Но вы можете попробовать установить ориентацию вручную в onResume:

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

это имеет больше.

1 голос
/ 03 ноября 2011

Я полагаю, что простое решение могло бы добавить поле внутри вашей видео активности:

boolean isClosing = false;

Установите isClosing на true в onDestroy или, что еще лучше, в onBackPressed (перед вызовом finish())

Теперь я предположил, что вы установили onConfigurationChanged для отслеживания изменений ориентации.

Итак, в вашем onConfigurationChanged Инкапсулируйте его с помощью if(!isClosing)

@Override
public void onConfigurationChanged(Configuration newConfig) 
{
  if(!isClosing){
      //YOUR OLD CODE
  }
}
0 голосов
/ 04 ноября 2011

onConfigurationChanged будет вызываться, только если вы добавите android: configChanges = "direction" к действию в файле манифеста.

Это говорит системе, что вы хотите вручную обрабатывать изменения ориентации, если у вас также есть android: screenOrientation = "landscape", вы также говорите системе, что действия должны отображаться в ландшафтном режиме (они должны работать вместе, чтобы дать вам то, что вы хотите)

0 голосов
/ 01 ноября 2011

Вы можете использовать совершенно другой макет для альбомного и портретного режима, который я рекомендую, поскольку вы можете использовать оба варианта по-разному.

Я бы тоже порекомендовал документацию по API: http://developer.android.com/guide/topics/manifest/activity-element.html#screen (особенно часть об обработке SavedBundle)

...