垃圾回收的原因:MediaPlayer的完成而不释放 [英] Garbage Collection causes : MediaPlayer finalized without being released

查看:692
本文介绍了垃圾回收的原因:MediaPlayer的完成而不释放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在很多的调试,我终于发现是什么原因造成这个错误!垃圾收集!

我在媒体视图中的视频播放,并在后台我要寻找从一个REST API的新视频。

时不时地,我看到了垃圾收集运行:

  02-22 13:14:57.969:D / dalvikvm(16888):GC_EXPLICIT释放152K,4%的自由6746K / 6979K,暂停2MS + 2ms的
 

和直后认为:

  02-22 13:14:57.969:W / MediaPlayer的-JNI(16888):MediaPlayer的完成而不释放
 

所以,我通过调用System.gc()每隔5秒进行了测试。

只要第一GC叫它发生!

  02-22 13:19:47.813:D / dalvikvm(17060):GC_EXPLICIT释放167K,5%的游离6745K / 7047K,暂停2MS + 2ms的----我叫GC
02-22 13:19:47.813:W / MediaPlayer的-JNI(17060):MediaPlayer的完成而不释放----视频播放阻断
 

我真的很新的Java和Android开发,所以请裸跟我来!

为什么会出现这种情况?我可以prevent呢?

播放视频:

 私人无效playMedia(INT playListIndex)抛出IOException异常{
        文件mediadir = GETDIR(TVR,Context.MODE_PRIVATE);
        文件清单= mediadir.listFiles();
        Log.i(媒体播放器,播放媒体!);
        字符串路径=文件清单[playListIndex] .getAbsolutePath();
        的FileInputStream的FileInputStream =新的FileInputStream(路径);
        最后开放的URI = Uri.parse(路径);
        字符串文件名=文件清单[playListIndex] .getName();
        如果(filename.contains(图像)){
            ImageView的=(ImageView的)findViewById(R.id.imageView);
            imageView.setVisibility(View.VISIBLE);
            imageView.setImageURI(URI);
            mHandler.postDelayed(新的Runnable(){
                公共无效的run(){
                    imageView.setVisibility(View.GONE);
                    imageView.setImageURI(URI);
                    onCompletion(空);
                }
            },4000);
        }否则,如果(filename.contains(视频)){

            MediaPlayer的PL =新的MediaPlayer();
            pl.setOnCompletionListener(本);
            pl.setDisplay(保持器);
            pl.setDataSource(fileInputStream.getFD());
            PL prepare()。
            pl.start();
        }
    }
 

和当它完成:

  @覆盖
    公共无效onCompletion(MediaPlayer的MP){
        Log.i(媒体播放器,播放下,请!);
        如果(熔点!= NULL){
            mp.release();
        }
//播放一个视频
        currentMedia ++;
        如果(currentMedia> playList.size() -  1){
            currentMedia = 0;
        }
        尝试 {
            playMedia(currentMedia);
        }赶上(IOException异常E){
            e.printStackTrace();
        }


    }
 

解决方案

我想这是因为你创建的方法的范围之内的媒体播放器,因此,该方法完成时,它超出范围。这意味着没有引用,所以是确定垃圾收集。

这意味着,它可以通过GC来free'd之前,它甚至被称为onCompletion,因此不会释放前清零。相反,你需要存储的引用,媒体播放器在你的类的成员变量。

After a lot of debugging I finally found what is causing this error! Garbage Collection!

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

And the straight after that:

02-22 13:14:57.969: W/MediaPlayer-JNI(16888): MediaPlayer finalized without being released

So I tested it by calling System.gc() every 5 seconds.

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

I am really new to Java and Android dev, so please bare with me!

Why does this happen? Can I prevent it?

Playing the video:

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();
        }
    }

And when it is done:

@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.

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的完成而不释放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆