在 RecyclerView 中释放 ExoPlayer
Release ExoPlayer in RecyclerView
我正在 RecyclerView 中实现 ExoPlayer。但是在滚动视频时会停止,但不会停止音频。
如何释放RecyclerView中的ExoPlayer?或者我怎样才能获得回收对象的位置,以便我能够释放 ExoPlayer?
这是我的数据对象
public class enter code here Video {
private String url;
private Context context;
Boolean playWhenReady = false;
int currentWindow = 0;
long playbackPosition = 0;
ExoPlayer player;
public Video(String url, Context context) {
this.url = url;
this.context = context;
}
public void setCurrentWindow(int currentWindow) {
this.currentWindow = currentWindow;
}
public void setPlaybackPosition(long playbackPosition) {
this.playbackPosition = playbackPosition;
}
public void setPlayWhenReady(Boolean playWhenReady) {
this.playWhenReady = playWhenReady;
}
public void setPlayer(ExoPlayer player) {
this.player = player;
}
public ExoPlayer getPlayer() {
return player;
}
public String getUrl() {
return url;
}
public Context getContext() {
return context;
}
public Boolean getPlayWhenReady() {
return playWhenReady;
}
public int getCurrentWindow() {
return currentWindow;
}
public long getPlaybackPosition() {
return playbackPosition;
}
}
这是我的适配器 Class:
我用 onViewRecycled() 方法尝试过,但因为我没有得到我无法释放播放器的位置。
public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.ViewHolder> {
private ArrayList<Video> mDataset;
public static class ViewHolder extends RecyclerView.ViewHolder {
public PlayerView mExoPlayer;
public ViewHolder(View itemView) {
super(itemView);
mExoPlayer = itemView.findViewById(R.id.video_view);
}
}
public VideoAdapter(ArrayList<Video> myDataset) {
mDataset = myDataset;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView=LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
initPlayer(holder,position);
}
private void initPlayer(ViewHolder holder,int position) {
mDataset.get(position).setPlayer(ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(mDataset.get(position).getContext()),
new DefaultTrackSelector(), new DefaultLoadControl()));
holder.mExoPlayer.setPlayer(mDataset.get(position).getPlayer());
mDataset.get(position).getPlayer().setPlayWhenReady(mDataset.get(position).getPlayWhenReady());
mDataset.get(position).getPlayer().seekTo(mDataset.get(position).getCurrentWindow(), mDataset.get(position).getPlaybackPosition());
Uri uri = Uri.parse(mDataset.get(position).getUrl());
MediaSource mediaSource = buildMediaSource(uri);
mDataset.get(position).getPlayer().prepare(mediaSource, true, false);
}
private MediaSource buildMediaSource(Uri uri) {
return new ExtractorMediaSource.Factory(
new DefaultHttpDataSourceFactory("exoplayer-codelab")).
createMediaSource(uri);
}
@Override
public int getItemCount() {
return mDataset.size();
}
@Override
public void onViewRecycled(@NonNull ViewHolder holder) {
super.onViewRecycled(holder);
}
}
我认为当播放器的视图被回收时释放播放器是最干净的。
适配器Class:
@Override
public void onViewRecycled(@NonNull ViewHolder holder) {
int position = holder.getAdapterPosition();
if (mDataset.get(position) != null) {
mDataset.get(position).getPlayer().release();
}
super.onViewRecycled(holder);
}
系统无法容纳多个 ExoPlayer
实例。它可以抛出 OOM Exception
。因此,当用户没有看到该项目时,您必须释放 ExoPlayer
。在这种情况下,我建议您使用 RecyclerView.Adapter
中的波纹管方法
override fun onViewDetachedFromWindow(holder: ViewHolder) {
holder.itemView.player?.stop()
holder.itemView.player?.release()
holder.itemView.player = null
super.onViewDetachedFromWindow(holder)
}
然后,在ViewHolde
r中class你应该检查,如果player == null
,你必须初始化它。
holder.yourplayername.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
}
@Override
public void onViewDetachedFromWindow(View v) {
holder.yourplayername.getPlayer().stop();
}
});
hi.i希望这段代码对你有帮助,因为对我有用。
我正在 RecyclerView 中实现 ExoPlayer。但是在滚动视频时会停止,但不会停止音频。
如何释放RecyclerView中的ExoPlayer?或者我怎样才能获得回收对象的位置,以便我能够释放 ExoPlayer?
这是我的数据对象
public class enter code here Video {
private String url;
private Context context;
Boolean playWhenReady = false;
int currentWindow = 0;
long playbackPosition = 0;
ExoPlayer player;
public Video(String url, Context context) {
this.url = url;
this.context = context;
}
public void setCurrentWindow(int currentWindow) {
this.currentWindow = currentWindow;
}
public void setPlaybackPosition(long playbackPosition) {
this.playbackPosition = playbackPosition;
}
public void setPlayWhenReady(Boolean playWhenReady) {
this.playWhenReady = playWhenReady;
}
public void setPlayer(ExoPlayer player) {
this.player = player;
}
public ExoPlayer getPlayer() {
return player;
}
public String getUrl() {
return url;
}
public Context getContext() {
return context;
}
public Boolean getPlayWhenReady() {
return playWhenReady;
}
public int getCurrentWindow() {
return currentWindow;
}
public long getPlaybackPosition() {
return playbackPosition;
}
}
这是我的适配器 Class: 我用 onViewRecycled() 方法尝试过,但因为我没有得到我无法释放播放器的位置。
public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.ViewHolder> {
private ArrayList<Video> mDataset;
public static class ViewHolder extends RecyclerView.ViewHolder {
public PlayerView mExoPlayer;
public ViewHolder(View itemView) {
super(itemView);
mExoPlayer = itemView.findViewById(R.id.video_view);
}
}
public VideoAdapter(ArrayList<Video> myDataset) {
mDataset = myDataset;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView=LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
initPlayer(holder,position);
}
private void initPlayer(ViewHolder holder,int position) {
mDataset.get(position).setPlayer(ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(mDataset.get(position).getContext()),
new DefaultTrackSelector(), new DefaultLoadControl()));
holder.mExoPlayer.setPlayer(mDataset.get(position).getPlayer());
mDataset.get(position).getPlayer().setPlayWhenReady(mDataset.get(position).getPlayWhenReady());
mDataset.get(position).getPlayer().seekTo(mDataset.get(position).getCurrentWindow(), mDataset.get(position).getPlaybackPosition());
Uri uri = Uri.parse(mDataset.get(position).getUrl());
MediaSource mediaSource = buildMediaSource(uri);
mDataset.get(position).getPlayer().prepare(mediaSource, true, false);
}
private MediaSource buildMediaSource(Uri uri) {
return new ExtractorMediaSource.Factory(
new DefaultHttpDataSourceFactory("exoplayer-codelab")).
createMediaSource(uri);
}
@Override
public int getItemCount() {
return mDataset.size();
}
@Override
public void onViewRecycled(@NonNull ViewHolder holder) {
super.onViewRecycled(holder);
}
}
我认为当播放器的视图被回收时释放播放器是最干净的。
适配器Class:
@Override
public void onViewRecycled(@NonNull ViewHolder holder) {
int position = holder.getAdapterPosition();
if (mDataset.get(position) != null) {
mDataset.get(position).getPlayer().release();
}
super.onViewRecycled(holder);
}
系统无法容纳多个 ExoPlayer
实例。它可以抛出 OOM Exception
。因此,当用户没有看到该项目时,您必须释放 ExoPlayer
。在这种情况下,我建议您使用 RecyclerView.Adapter
override fun onViewDetachedFromWindow(holder: ViewHolder) {
holder.itemView.player?.stop()
holder.itemView.player?.release()
holder.itemView.player = null
super.onViewDetachedFromWindow(holder)
}
然后,在ViewHolde
r中class你应该检查,如果player == null
,你必须初始化它。
holder.yourplayername.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
}
@Override
public void onViewDetachedFromWindow(View v) {
holder.yourplayername.getPlayer().stop();
}
});
hi.i希望这段代码对你有帮助,因为对我有用。