1

Я пишу приложение для Android, которое воспроизводит оба изображения (показано на 10 секунд) и видео. Я использовал макет с VideoView и ImageView для этого. Макет XML ниже:Android: OutOfMemoryError при воспроизведении видео и изображений

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" 
android:layout_height="match_parent" android:background="#0099cc" 
tools:context="nahtlos.de.lackmannvideo.VideoActivity"> 

<VideoView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:keepScreenOn="true" 
    android:id="@+id/mediaView" /> 

<ImageView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:keepScreenOn="true" 
    android:id="@+id/imageView" /> 

</RelativeLayout> 

Однако я открываю папку на устройстве и воспроизвожу медиа в цикле. Поэтому mediaList содержит пути к файлам каталога. Для этой задачи я использую отдельный поток. Смотрите ниже код:

public class MediaControlThread extends Thread { 
    public static List<String> mediaList = new ArrayList<String>(); 
    private VideoView mediaView; 
    private ImageView imageView; 
    MyPhotoActivity activity; 
    private int currentVideo = 0; 

    public MediaControlThread(MyPhotoActivity activity, VideoView mediaView, ImageView imageView) { 
    this.mediaView = mediaView; 
    this.imageView = imageView; 
    this.activity = activity; 
} 

    @Override 
    public void run() { 
    try { 
     while(mediaList.size() == 0) { 
      Thread.sleep(1000); 
     } 
     Thread.sleep(3000); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    playMedia(mediaList.get(0)); 
    } 

    private void completePlaying() { 
    currentVideo++; 
    if (currentVideo > mediaList.size() - 1) { 
     currentVideo = 0; 
    } 
    final MediaControlThread me = this; 
    activity.runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      imageView.setVisibility(View.INVISIBLE); 
      mediaView.setVisibility(View.INVISIBLE); 
     } 
    }); 
    Thread waitThread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      try { 
       Thread.sleep(200); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
    waitThread.start(); 
    try { 
     waitThread.join(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    playMedia(mediaList.get(currentVideo)); 
    } 

    private void playMedia(final String mediaPath) { 
    try { 
     if (checkFileForImage(mediaPath)) { 
      final MediaControlThread me = this; 
      final Bitmap bm = BitmapFactory.decodeFile(mediaPath); 
      activity.runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        me.imageView.setVisibility(View.VISIBLE); 
        me.imageView.setImageBitmap(bm); 
       } 
      }); 
      Thread waitThread = new Thread(new Runnable() { 
       @Override 
       public void run() { 
        try { 
         Thread.sleep(AppSettings.secondsToShowPicture * 1000); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      }); 
      waitThread.start(); 
      waitThread.join(); 
      if(bm != null) { 
       bm.recycle(); 
      } 
      completePlaying(); 
     } else { 
      final MediaControlThread me = this; 
      activity.runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        me.mediaView.setVisibility(View.VISIBLE); 
        me.mediaView.setVideoPath(mediaPath); 
        me.mediaView.start(); 
       } 
      }); 
      if(!mediaView.isPlaying()) { 
       while (!mediaView.isPlaying()) { 
        Thread.sleep(100); 
       } 
      } 
      while(mediaView.isPlaying()) { 
       Thread.sleep(100); 
      } 
      activity.runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        me.mediaView.stopPlayback(); 
        me.mediaView.suspend(); 
        me.mediaView.destroyDrawingCache(); 
       } 
      }); 
      completePlaying(); 
     } 
     } catch (IllegalArgumentException e) { 
     Log.d("MyMediaPlayerControl", e.getMessage()); 
     } catch (IllegalStateException e) { 
     Log.d("MyMediaPlayerControl", e.getMessage()); 
     } catch (InterruptedException e) { 
     e.printStackTrace(); 
     } 
    } 

    private boolean checkFileForImage(String fileName) { 
    String file = fileName.toLowerCase(); 
    return file.endsWith(".jpg") || 
      file.endsWith(".img") || 
      file.endsWith(".bmp") || 
      file.endsWith(".jpeg") || 
      file.endsWith(".ico") || 
      file.endsWith(".tif"); 
    } 
} 

Все работает отлично для начала, но примерно через 5 минут я получаю OutOfMemoryException:

10-23 14:20:46.417 379-379/xxx E/IMGSRV: :0: PVRDRMOpen: TP3, ret = 50 
10-23 14:20:46.427 379-379/xxx E/IMGSRV: :0: PVRDRMOpen: TP3, ret = 53 
10-23 14:20:46.427 379-379/xxx E/IMGSRV: :0: PVRDRMOpen: TP3, ret = 54 
10-23 14:20:46.427 379-379/xxx E/IMGSRV: :0: PVRDRMOpen: TP3, ret = 54 
10-23 14:20:46.437 379-379/xxx E/IMGSRV: :0: PVRDRMOpen: TP3, ret = 54 
10-23 14:20:46.447 379-379/xxx E/IMGSRV: :0: PVRDRMOpen: TP3, ret = 56 
10-23 14:24:23.687 379-716/xxx E/dalvikvm-heap: Out of memory on a 36000016-byte allocation. 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime: FATAL EXCEPTION: Thread-532 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime: Process: xxx, PID: 379 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime: java.lang.OutOfMemoryError 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:613) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:589) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:369) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:395) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:87) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.completePlaying(MediaControlThread.java:80) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:137) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.completePlaying(MediaControlThread.java:80) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:137) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.completePlaying(MediaControlThread.java:80) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:137) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.completePlaying(MediaControlThread.java:80) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:137) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.completePlaying(MediaControlThread.java:80) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:137) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.completePlaying(MediaControlThread.java:80) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:137) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.completePlaying(MediaControlThread.java:80) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:137) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.completePlaying(MediaControlThread.java:80) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:137) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.completePlaying(MediaControlThread.java:80) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:137) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.completePlaying(MediaControlThread.java:80) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:137) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.completePlaying(MediaControlThread.java:80) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:137) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.completePlaying(MediaControlThread.java:80) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:137) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.completePlaying(MediaControlThread.java:80) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:137) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.completePlaying(MediaControlThread.java:80) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:137) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.completePlaying(MediaControlThread.java:80) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:137) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.completePlaying(MediaControlThread.java:80) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime:  at xxx.MediaControlThread.playMedia(MediaControlThread.java:137) 
10-23 14:24:23.787 379-716/xxx E/AndroidRuntime: at xxx.MediaControlThread.comple 

Кто-нибудь может дать ключ ??? Я пытаюсь реализовать этот образ и просмотрщик видео в течение нескольких дней! Спасибо!

+1

Если проблема связана с большим размером ввода данных, то вы можете использовать android: largeheap = "true" в файле манифеста в теге Application. Проверьте, помогает ли это вам. –

+0

У меня есть попытка. У меня около 50 изображений (25 из них 4000x2250px и 25 из них с разрешением 1600x1200px) и 25 видео (по 5 Мбайт каждый). Вся папка занимает около 130 МБ. Это слишком много ??? –

+0

да, это позволит решить проблему –

ответ

0

Обнаружена проблема! Нет возможности для просмотра как видео, так и изображений с помощью SurfaceView. Смотрите также этот пост:

Android SurfaceView: Show Video after Images

То есть, к сожалению, ожидаемое поведение. Из-за причуды на Android, когда вы нарисовали на поверхности с Canvas, вы ничего не можете сделать. [...]

Смежные вопросы