Java 如何在Android MediaPlayer中进行内存管理?
我用的是安卓4.4.4版本。我的应用程序使用了MediaPlayer 我已在设备中获取媒体列表,并将每个媒体放入可变列表中。接下来是媒体播放的for循环 但是,过了一段时间它就死了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
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;
}