Android:播放视频和图像时出现OutOfMemoryError

时间:2015-10-23 12:35:17

标签: android android-imageview android-mediaplayer android-videoview

我正在编写一个Android应用,可播放两张图片(显示10秒)和视频。我使用了带有VideoView和ImageView的布局。下面的布局XML:

<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 个答案:

答案 0 :(得分:0)

发现问题了!使用SurfaceView无法同时查看视频和图像。另见这篇文章:

Android SurfaceView: Show Video after Images

  

不幸的是,这是预期的行为。由于Android中的怪癖,一旦你在带有画布的Surface上绘制,你就无法做任何其他事情。 [...]