Garbage Collection causes : MediaPlayer finalized without being released(垃圾收集原因:MediaPlayer 未发布就完成了)
问题描述
经过大量调试,我终于找到了导致此错误的原因!垃圾收集!
After a lot of debugging I finally found what is causing this error! Garbage Collection!
我在媒体视图中播放了一个视频,我正在后台寻找来自 Rest API 的新视频.
I have a video playing in media view and in the background I am looking for new videos from a Rest API.
我时不时地看到垃圾收集在运行:
Every now and then I see the Garbage collection running:
02-22 13:14:57.969: D/dalvikvm(16888): GC_EXPLICIT freed 152K, 4% free 6746K/6979K, paused 2ms+2ms
紧随其后的是:
02-22 13:14:57.969: W/MediaPlayer-JNI(16888): MediaPlayer finalized without being released
所以我每 5 秒调用一次 System.gc() 对其进行测试.
So I tested it by calling System.gc() every 5 seconds.
一旦第一次 GC 被调用,它就会发生!
As soon as the first GC is called it happens!
02-22 13:19:47.813: D/dalvikvm(17060): GC_EXPLICIT freed 167K, 5% free 6745K/7047K, paused 2ms+2ms ---- I call GC
02-22 13:19:47.813: W/MediaPlayer-JNI(17060): MediaPlayer finalized without being released ---- VIDEO PLAY INTERRUPTED
为什么会这样?我可以预防吗?
Why does this happen? Can I prevent it?
播放视频:
private void playMedia(int playListIndex) throws IOException {
File mediadir = getDir("tvr", Context.MODE_PRIVATE);
filelist = mediadir.listFiles();
Log.i("media player", "play media!");
String path = filelist[playListIndex].getAbsolutePath();
FileInputStream fileInputStream = new FileInputStream(path);
final Uri uri = Uri.parse(path);
String filename = filelist[playListIndex].getName();
if (filename.contains("image")) {
imageView = (ImageView)findViewById(R.id.imageView);
imageView.setVisibility(View.VISIBLE);
imageView.setImageURI(uri);
mHandler.postDelayed(new Runnable() {
public void run() {
imageView.setVisibility(View.GONE);
imageView.setImageURI(uri);
onCompletion(null);
}
}, 4000);
} else if (filename.contains("video")) {
MediaPlayer pl = new MediaPlayer();
pl.setOnCompletionListener(this);
pl.setDisplay(holder);
pl.setDataSource(fileInputStream.getFD());
pl.prepare();
pl.start();
}
}
当它完成时:
@Override
public void onCompletion(MediaPlayer mp) {
Log.i("media player", "play next please!");
if (mp != null) {
mp.release();
}
// play next video
currentMedia++;
if (currentMedia > playList.size() - 1) {
currentMedia = 0;
}
try {
playMedia(currentMedia);
} catch (IOException e) {
e.printStackTrace();
}
}
推荐答案
我认为这是因为您在方法范围内创建媒体播放器,因此,当方法完成时,它超出了范围.这意味着没有引用,因此可以进行垃圾收集.
I think this is because you create the media player within the scope of the method, therefore, when the method completes, it goes out of scope. This means there are no references, so is ok for garbage collection.
这意味着,它甚至可以在调用 onCompletion 之前被 GC 释放,因此在清除之前不会释放.相反,您需要将媒体播放器的引用作为成员变量存储在您的类中.
This means, it can be free'd by the GC before it has even called onCompletion, hence won't release before cleared. Instead, you need to store a reference to the media player as a member variable in your class.
这篇关于垃圾收集原因:MediaPlayer 未发布就完成了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:垃圾收集原因:MediaPlayer 未发布就完成了
基础教程推荐
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01