Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Android MediaPlayer中进行内存管理?_Java_Android_Kotlin_Memory Leaks_Android Mediaplayer - Fatal编程技术网

Java 如何在Android MediaPlayer中进行内存管理?

Java 如何在Android MediaPlayer中进行内存管理?,java,android,kotlin,memory-leaks,android-mediaplayer,Java,Android,Kotlin,Memory Leaks,Android Mediaplayer,我用的是安卓4.4.4版本。我的应用程序使用了MediaPlayer 我已在设备中获取媒体列表,并将每个媒体放入可变列表中。接下来是媒体播放的for循环 但是,过了一段时间它就死了 10-18 12:58:29.599 1466-1466/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.hanmedia.android, PID: 1466 java.lang.OutOfMemoryError at a

我用的是安卓4.4.4版本。我的应用程序使用了MediaPlayer

我已在设备中获取媒体列表,并将每个媒体放入可变列表中。接下来是媒体播放的for循环

但是,过了一段时间它就死了

10-18 12:58:29.599 1466-1466/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.hanmedia.android, PID: 1466
    java.lang.OutOfMemoryError
        at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
        at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:594)
        at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:429)
        at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:840)
        at android.content.res.Resources.loadDrawable(Resources.java:2110)
        at android.content.res.Resources.getDrawable(Resources.java:700)
        at android.graphics.drawable.AnimationDrawable.inflate(AnimationDrawable.java:282)
        at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:937)
        at android.graphics.drawable.Drawable.createFromXml(Drawable.java:877)
        at android.content.res.Resources.loadDrawable(Resources.java:2092)
        at android.content.res.TypedArray.getDrawable(TypedArray.java:602)
        at android.widget.ProgressBar.<init>(ProgressBar.java:294)
        at android.widget.ProgressBar.<init>(ProgressBar.java:246)
        at android.widget.AbsSeekBar.<init>(AbsSeekBar.java:69)
        at android.widget.SeekBar.<init>(SeekBar.java:83)
        at androidx.appcompat.widget.AppCompatSeekBar.<init>(AppCompatSeekBar.java:50)
        at androidx.appcompat.widget.AppCompatSeekBar.<init>(AppCompatSeekBar.java:45)
        at androidx.appcompat.app.AppCompatViewInflater.createSeekBar(AppCompatViewInflater.java:256)
        at androidx.appcompat.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:163)
        at androidx.appcompat.app.AppCompatDelegateImpl.createView(AppCompatDelegateImpl.java:1551)
        at androidx.appcompat.app.AppCompatDelegateImpl.onCreateView(AppCompatDelegateImpl.java:1602)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:684)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:758)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
        at android.widget.MediaController.makeControllerView(MediaController.java:244)
        at android.widget.MediaController.setAnchorView(MediaController.java:232)
        at android.widget.VideoView.attachMediaController(VideoView.java:380)
        at android.widget.VideoView.openVideo(VideoView.java:349)
        at android.widget.VideoView.access$2100(VideoView.java:71)
        at android.widget.VideoView$7.surfaceCreated(VideoView.java:607)
        at android.view.SurfaceView.updateWindow(SurfaceView.java:572)
        at android.view.SurfaceView.access$000(SurfaceView.java:86)
        at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:175)
        at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:847)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1876)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1001)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5680)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
        at android.view.Choreographer.doCallbacks(Choreographer.java:574)
        at android.view.Choreographer.doFrame(Choreographer.java:544)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5001)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:815)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:631)
        at dalvik.system.NativeStart.main(Native Method)

我认为问题在于您正在创建MediaPlayer的多个实例,这会导致OutOfMemoryError异常。另外,完成播放后,不要忘记释放MediaPlayer实例。 根据MediaPlayer文档:

还建议,一旦不再使用MediaPlayer对象,立即调用release(),以便可以立即释放与MediaPlayer对象关联的内部播放器引擎使用的资源。资源可能包括单例资源,如硬件加速组件,调用release()失败可能会导致MediaPlayer对象的后续实例退回到软件实现或完全失败。一旦MediaPlayer对象处于结束状态,就无法再使用它,也无法将其恢复到任何其他状态

在MediaItemPlayer中添加一个方法,以便在使用后释放MediaPlayer:

    private fun releaseMediaPlayer(){
       if (player.isPlaying()) {
           player.stop();
       }
       player.reset();
       player.release();
       player = null;
}
播放完媒体文件后,从NormalFragment调用releaseMediaPlayer

// MediaItemPlayer class
// class MediaItemPlayer(private val context : Context, private val mediaLink : DeviceWithMediaLink)

private var repeatCount = 0
    private var ready : Boolean = false
    private var startFlag = false
    private var startIgnoreFlag = false
    private var prepareFlag = false

    private lateinit var player : MediaPlayer
    private lateinit var nextListener: PlayerEventListener

fun start(){
        if(ready) {
            logger.i("ready [${mediaLink.mediaLinkType}]${mediaLink.media.originalName}")
            when (mediaLink.media.mediaType) {
                MediaType.TEXT, MediaType.PICTURE -> {
                    val delayTime = mediaLink.waitTime * (mediaLink.repeatCount + 1)
                    logger.i("[${mediaLink.mediaLinkType}] delay $delayTime")
                    view.postDelayed({
                        goNext()
                    }, delayTime)
                }
                MediaType.VIDEO -> {
                    logger.i("[${mediaLink.mediaLinkType}] Video start")
                    if(prepareFlag){
                        player.start()
                    }else{
                        view.postDelayed({
                            if(!prepareFlag) {
                                logger.e("[${mediaLink.mediaLinkType}] not prepare")
                                startIgnoreFlag = true
                                logger.e("[${mediaLink.mediaLinkType}] start ignore and play next video")
                                nextListener.next()
                            }
                        }, 2000)
                        startFlag = true
                    }
                }
            }
            context.runOnUiThread {
                view.visibility = View.VISIBLE
            }
        }else{
            logger.i("not ready [${mediaLink.mediaLinkType}]${mediaLink.media.originalName}")
            goNext()
        }
    }

    private fun goNext(){
        nextListener.next()
        context.runOnUiThread {
            view.visibility = View.GONE
        }
    }
    private fun releaseMediaPlayer(){
       if (player.isPlaying()) {
           player.stop();
       }
       player.reset();
       player.release();
       player = null;
}