ExoPlayer2 - 如何从片段中释放

时间:2017-07-05 20:32:42

标签: android android-fragments exoplayer2.x

我有一个活动有2个片段(不是ViewPager)&想在其中一个片段中使用ExoPlayer2来播放内容。最初的片段显示了一个内容列表&单击时,显示第二个片段播放所选内容。然而,当我点击回到初始片段时,我仍然可以听到播放的内容;好像第二个片段仍处于打开状态。我(尝试)以这种方式释放玩家:

@Override
public void onStop() {
    super.onStop();
    releasePlayer();
}

public void releasePlayer() {

    if (player != null) {
        player.setPlayWhenReady(true);
        player.stop();
        player.release();
        player = null;
        trackSelector = null;
        simpleExoPlayerView.setPlayer(null);
        simpleExoPlayerView = null;
        System.out.println("releasePlayer");
    }
}

我读过this但它没有提供太多解决方案。另外,阅读几篇在ViewPager片段中使用ExoPlayer的帖子,但不完全确定这些示例是如何发布播放器的。遵循发现here的演示应用程序中的releasePlayer()方法,但没有运气。从onPause(),onDetach(),onDestroyView()调用releasePlayer()但它没有区别。

在将听众添加到播放器之后设置了一些日志记录,但没有看到任何可以解释它为什么不发布的日志...

07-05 19:01:07.216 2529-2643/? V/RenderScript: 0xe0494000 Launching thread(s), CPUs 4
07-05 19:01:11.871 3064-3064/? V/MediaCodecInfo: Listener-onPlayerStateChanged...
07-05 19:01:11.876 3064-3064/? V/MediaCodecInfo: Listener-onPlayerStateChanged...
07-05 19:01:11.904 3064-3064/? V/MediaCodecInfo: Listener-onPlayerStateChanged...
07-05 19:01:11.904 3064-3064/? V/MediaCodecInfo: Listener-onTimelineChanged...
07-05 19:01:11.904 3064-3064/? V/MediaCodecInfo: Listener-onLoadingChanged...
07-05 19:01:11.904 3064-3064/? V/MediaCodecInfo: Listener-onPlayerStateChanged...
07-05 19:01:11.904 3064-3064/? V/MediaCodecInfo: Listener-onTimelineChanged...
07-05 19:01:11.904 3064-3064/? V/MediaCodecInfo: Listener-onLoadingChanged...
07-05 19:01:12.467 3064-3064/? V/MediaCodecInfo: Listener-onTimelineChanged...
07-05 19:01:12.468 3064-3064/? V/MediaCodecInfo: Listener-onTimelineChanged...
07-05 19:01:12.515 3064-3099/? V/SoftFFmpegVideo: got OMX_IndexParamPortDefinition, width: 320, height: 180
07-05 19:01:12.708 3064-3064/? V/MediaCodecInfo: Listener-onPlayerStateChanged...
07-05 19:01:12.708 3064-3064/? V/MediaCodecInfo: Listener-onPlayerStateChanged...
07-05 19:01:13.380 3064-3064/? V/MediaCodecInfo: Listener-onLoadingChanged...
07-05 19:01:13.655 3064-3064/? V/MediaCodecInfo: Listener-onLoadingChanged...
07-05 19:01:18.528 3064-3099/? V/SoftFFmpegVideo: ~SoftFFmpegVideo

尝试按下按钮但是失败了

fragmentExoBinding.button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            System.out.println("button click");
            releasePlayer();
        }
    });

每当我把它关闭时(使用背部按下,回家或最近),它都会崩溃,而那里不再是玩家。使用if(player!= null)更新了releasePlayer()方法,但即使按下按钮,仍然可以听到播放的内容。

2 个答案:

答案 0 :(得分:2)

我在Activity中使用ExoPlayer,我正在使用两个步骤。 onPause我正在停止播放:

private SimpleExoPlayer player;     
@Override
protected void onPause() {
    super.onPause();

    // Pause video if it's playing
    if (isVideoPlaying()) {
        if (player != null)
            player.setPlayWhenReady(false);
    }
}

onDestroy我释放了播放器

@Override
protected void onDestroy() {
    releasePlayer();
    super.onDestroy();
}

private void releasePlayer() {
        if (player != null) {
            player.stop();
            player.release();
            player = null;
        }
    }

答案 1 :(得分:0)

我有一个理论,但我不确定。为了避免写出超过9000条评论,我会发布它是一个答案。

  1. 如果您在布局中添加<Button>onClick()致电releasePlayer();,播放器是否会停止(并获释)?

  2. 如果上述方法有效,则覆盖您的活动onBackPressed(),然后在调用super.onBackPressed()之前,获取您的片段实例并调用releasePlayer()。你可以让你的片段实现一些接口,如果你想取悦Java人并假装有一天你将对它进行单元测试......或者你可以将方法公开并将其投射到你的片段并花费5秒而不是浪费5分钟和16kb的记忆:)

  3. 无论如何,界面示例:

    public interface BackHandlerListener {
        void onBackPressed();
    }
    

    然后有你的片段......

    class MyFragment extends Fragment implements BackHandlerListener {
        @Override
        public void onBackPressed() {
            releasePlayer();
        }
    }
    

    和你的活动......

        @Override
        public void onBackPressed() {
            // get your fragment’s instance
            Fragment fragment =
             getSupportFragmentManager() 
                .findFragmentById(R.id.your_fragment_container);
    
            if (fragment instanceof BackHandlerListener) {
                ((BackHandlerListener) fragment).onBackPressed();
            }
    
            super.onBackPressed();
        }
    

    你得到了演习。

    1. 如果#1不起作用,那么你的玩家就会发生一些奇怪的事情,拒绝停止,但似乎与Fragment的生命周期有点无关。 (*)
    2. (*)除非问题是当片段停止并且引用被泄露(因为它是本机代码)时媒体播放器正在死亡。如果是这种情况,恐怕我必须阅读更多有关ExoPlayer2如何运作的信息(上次我使用媒体播放器,ExoPlayer1是一个“测试版”的东西,承诺更好的体验,但并不适用于所有设备)。在那些日子里,我不得不使用Android服务来保持MediaPlayer并播放并向我的服务发送广播意图来命令它。 ¯_(ツ)_ /¯