如何处理应用后台以恢复我用 Dagger2 注入的 Exoplayer?
How do I deal with app backgrounding to restore the Exoplayer, which I inject with Dagger2?
我有一个 Fragment,其中包含我随 Dagger 2 一起提供的 Exoplayer 实例,如下所示:
@Inject SimpleExoPlayer mPlayer;
在大多数情况下,这很有效,我可以在我的播放器上播放东西,状态在生命周期变化时正确恢复等。
我遇到的问题是,当我点击概览按钮,导航到另一个应用程序,然后返回时,播放器处于黑屏状态,搜索栏已恢复到其保存的位置,但它不会播放任何内容,也不会响应 UI 上的播放命令,并且在重新创建片段之前一直保持黑色。
我现在正在尝试修改一些东西,让我的代码像在 this code lab:
中一样处理播放器
private void releasePlayer() {
if (player != null) {
playbackPosition = player.getCurrentPosition();
currentWindow = player.getCurrentindowIndex();
playWhenReady = player.getPlayWhenReady();
player.release();
player = null;
}
}
上面API23.
上面onStop()
应该调用的
initializePlayer()
在 onStart()
中被调用,它应该看起来像这样。在我的例子中,唯一的区别是我不创建播放器,Dagger 在创建时为我创建。
private void initializePlayer() {
player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(), new DefaultLoadControl());
playerView.setPlayer(player);
player.setPlayWhenReady(playWhenReady);
player.seekTo(currentWindow, playbackPosition);
[...]
}
请注意,这两个代码片段均来自链接的代码实验室。
这就是我与 Dagger 斗争的地方。创建或重新创建 Fragment 时,一切正常,因为 Dagger 会为我提供一个播放器,但是如果我在 onStop()
中将播放器设置为 null
,并且 Fragment 没有被销毁,它是恢复并且只调用 onStart() 和 onResume(),Dagger 不会创建新实例,除非我错过了如何创建的方法。
任何人都可以指出 Dagger2 和 ExoPlayer 设置的一些代码示例,最好是使用片段吗?
也请对此有所了解:)
编辑:感谢@David Medenjak
解决了
在得到有关使用 Provider<> 的提示后,我通过以下方法解决了这个问题:
@Inject Provider<SimpleExoPlayer> mSimpleExoPlayerProvider
和:
SimpleExoPlayer mPlayer
因此,当我在 onStart
中初始化播放器时,如果没有实例附加到 mPlayer,我将从 Provider 获取一个新的播放器实例,并保留该播放器实例,直到我在 onStop
中释放播放器我将 mPlayer 设置为 null.
if (mPlayer == null) {
// Get new instance of player if mPlayer is null
mPlayer = mSimpleExoPlayerProvider.get();
}
Dagger will not create a new instance, unless I am missing a way on how to this.
如果你只想每次从 Dagger 获取一个新实例,那么你应该注入 Provider<SimpleExoPlayer>
并在需要新对象时调用 provider.get()
。
为此播放器需要 unscoped,否则你每次都会得到相同的对象。
我有一个 Fragment,其中包含我随 Dagger 2 一起提供的 Exoplayer 实例,如下所示:
@Inject SimpleExoPlayer mPlayer;
在大多数情况下,这很有效,我可以在我的播放器上播放东西,状态在生命周期变化时正确恢复等。
我遇到的问题是,当我点击概览按钮,导航到另一个应用程序,然后返回时,播放器处于黑屏状态,搜索栏已恢复到其保存的位置,但它不会播放任何内容,也不会响应 UI 上的播放命令,并且在重新创建片段之前一直保持黑色。
我现在正在尝试修改一些东西,让我的代码像在 this code lab:
中一样处理播放器private void releasePlayer() {
if (player != null) {
playbackPosition = player.getCurrentPosition();
currentWindow = player.getCurrentindowIndex();
playWhenReady = player.getPlayWhenReady();
player.release();
player = null;
}
}
上面API23.
上面onStop()
应该调用的
initializePlayer()
在 onStart()
中被调用,它应该看起来像这样。在我的例子中,唯一的区别是我不创建播放器,Dagger 在创建时为我创建。
private void initializePlayer() {
player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(), new DefaultLoadControl());
playerView.setPlayer(player);
player.setPlayWhenReady(playWhenReady);
player.seekTo(currentWindow, playbackPosition);
[...]
}
请注意,这两个代码片段均来自链接的代码实验室。
这就是我与 Dagger 斗争的地方。创建或重新创建 Fragment 时,一切正常,因为 Dagger 会为我提供一个播放器,但是如果我在 onStop()
中将播放器设置为 null
,并且 Fragment 没有被销毁,它是恢复并且只调用 onStart() 和 onResume(),Dagger 不会创建新实例,除非我错过了如何创建的方法。
任何人都可以指出 Dagger2 和 ExoPlayer 设置的一些代码示例,最好是使用片段吗? 也请对此有所了解:)
编辑:感谢@David Medenjak
解决了在得到有关使用 Provider<> 的提示后,我通过以下方法解决了这个问题:
@Inject Provider<SimpleExoPlayer> mSimpleExoPlayerProvider
和:
SimpleExoPlayer mPlayer
因此,当我在 onStart
中初始化播放器时,如果没有实例附加到 mPlayer,我将从 Provider 获取一个新的播放器实例,并保留该播放器实例,直到我在 onStop
中释放播放器我将 mPlayer 设置为 null.
if (mPlayer == null) {
// Get new instance of player if mPlayer is null
mPlayer = mSimpleExoPlayerProvider.get();
}
Dagger will not create a new instance, unless I am missing a way on how to this.
如果你只想每次从 Dagger 获取一个新实例,那么你应该注入 Provider<SimpleExoPlayer>
并在需要新对象时调用 provider.get()
。
为此播放器需要 unscoped,否则你每次都会得到相同的对象。