从 viewpager 2 停止并释放 exoplayer

Posted

技术标签:

【中文标题】从 viewpager 2 停止并释放 exoplayer【英文标题】:stop and release exoplayer from viewpager 2 【发布时间】:2020-10-11 09:42:54 【问题描述】:

我正在使用带有 ViewPager2 的 Exoplayer。

Home Fragment.java

public class HomeFragment extends Fragment 


    View view;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 

        view= inflater.inflate(R.layout.fragment_home, container, false);

     

        ViewPager2 verticalViewPager = view.findViewById(R.id.vPager);
     
        verticalViewPager.setOrientation(ViewPager2.ORIENTATION_VERTICAL);

        ArrayList<VideoDataModel> dataset = new ArrayList<VideoDataModel>();
        VideoDataModel videoData = new VideoDataModel();
        videoData.setId("1");
        videoData.setUrl("https://cdn.videvo.net/videvo_files/video/free/2019-02/small_watermarked/181004_10_LABORATORIES-SCIENCE_22_preview.webm");
        videoData.setUserid("112800058400468785815");
        videoData.setDescription("Video 1");
        dataset.add(videoData);

        VideoDataModel videoData1 = new VideoDataModel();
        videoData1.setId("2");
        videoData1.setUrl("https://cdn.videvo.net/videvo_files/video/premium/video0122/small_watermarked/100a%20Factory_preview.webm");
        videoData1.setUserid("112800058400468785815");
        videoData1.setDescription("Video 2");
        dataset.add(videoData1);




        ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(view.getContext(),dataset);
        verticalViewPager.setAdapter(viewPagerAdapter);


        return  view;

    





    @Override
    public void onResume() 
        super.onResume();


        BottomNavigationView bottomNavigationView = ((MainActivity) getActivity()).findViewById(R.id.bottom_navigation);
        bottomNavigationView.setBackground( new ColorDrawable(getResources().getColor(android.R.color.black)));
        bottomNavigationView.setItemTextColor(ColorStateList.valueOf(Color.WHITE));
        bottomNavigationView.setItemIconTintList(ColorStateList.valueOf(Color.WHITE));
    

fragment_home.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:background="#000000"
    tools:context=".Home.HomeFragment">



    <androidx.viewpager2.widget.ViewPager2
        android:layout_
        android:layout_
        android:id="@+id/vPager"/>


</FrameLayout>

ViewpagerAdapter.java

public class ViewPagerAdapter extends RecyclerView.Adapter<ViewPagerAdapter.ViewHolder> 

    Context mContext;


    LinearLayout sourdImage_layout;
    ImageView soundImage;
    LinearLayout shared_layout;
    LinearLayout comment_layout;
    LinearLayout like_layout;
    FrameLayout profile_lt;
    LinearLayout gift_layout;
    LinearLayout collab_layout;
    Button check_bal_btn;
    LinearLayout upload;
    SharedPreferences pref;
    LinearLayout shop;





    ArrayList<VideoDataModel> videoDataset;

    public ViewPagerAdapter(Context mContext, ArrayList<VideoDataModel> videoDataset) 
        this.mContext = mContext;
        this.videoDataset = videoDataset;
    

    @NonNull
    @Override
    public ViewPagerAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup container, int viewType) 

        LayoutInflater mLayoutInflater = LayoutInflater.from(container.getContext());
        View itemView = mLayoutInflater.inflate(R.layout.customviewpager, container, false);
        ViewHolder viewHolder = new ViewHolder(itemView);



        soundImage = itemView.findViewById(R.id.sound_image);
        sourdImage_layout = itemView.findViewById(R.id.sound_image_layout);
        shared_layout = itemView.findViewById(R.id.shared_layout);
        comment_layout = itemView.findViewById(R.id.comment_layout);
        like_layout = itemView.findViewById(R.id.like_layout);
        profile_lt = itemView.findViewById(R.id.profile_lt);
        gift_layout = itemView.findViewById(R.id.gift_layout);
        collab_layout = itemView.findViewById(R.id.collab_layout);
        upload = itemView.findViewById(R.id.upload);
        shop = itemView.findViewById(R.id.shop);


        like_layout.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                Toast.makeText(view.getContext(),"Released",Toast.LENGTH_SHORT).show();

            
        );


        pref = mContext.getSharedPreferences(Variables.pref_name, 0); // 0 - for private mode

        upload.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                if( pref.getBoolean(Variables.islogin,false)!=false)
                
                    Intent intent1 = new Intent(mContext, VideoRecorderActivity.class);
                    mContext.startActivity(intent1);
                
                else
                
                    Toast.makeText(mContext,"Pls Login to Continue...",Toast.LENGTH_SHORT).show();
                
            
        );

        shop.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                if( pref.getBoolean(Variables.islogin,false)!=false)
                
                    Intent intent1 = new Intent(mContext, ShopActivity.class);
                    mContext.startActivity(intent1);
                
                else
                
                    Toast.makeText(mContext,"Pls Login to Continue...",Toast.LENGTH_SHORT).show();
                
            
        );


        final BottomSheetDialog CommentBottomSheetDialog = new BottomSheetDialog(mContext);
        View sheetView =  mLayoutInflater.inflate(R.layout.comment_bottom_sheet, null);
        CommentBottomSheetDialog.setContentView(sheetView);

//
        final BottomSheetDialog GiftBottomSheetDialog = new BottomSheetDialog(mContext);
        View giftSheetView =  mLayoutInflater.inflate(R.layout.gift_bottom_sheet, null);
        check_bal_btn = giftSheetView.findViewById(R.id.check_bal_btn);
        GiftBottomSheetDialog.setContentView(giftSheetView);

        check_bal_btn.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                Intent intent1 = new Intent(mContext, WalletActivity.class);
                mContext.startActivity(intent1);
            
        );

        final BottomSheetDialog collabBottomSheetDialog = new BottomSheetDialog(mContext);
        View collabSheetView =  mLayoutInflater.inflate(R.layout.collab_bottom_sheet, null);
        collabBottomSheetDialog.setContentView(collabSheetView);

        RotateAnimation rotate = new RotateAnimation(
                0, 360,
                Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF, 0.5f
        );
        rotate.setDuration(4800);
        rotate.setRepeatCount(Animation.INFINITE);
        sourdImage_layout.startAnimation(rotate);


        //share button
        shared_layout.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                Intent intent = new Intent();
                intent.setAction(Intent.ACTION_SEND);
                intent.putExtra(Intent.EXTRA_TEXT,"I suggest this app for you : https://play.google.com/store/apps/details?id=com.android.chrome");
                intent.setType("text/plain");
                mContext.startActivity(intent);
            
        );


        //Comments
        comment_layout.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                if( pref.getBoolean(Variables.islogin,false)!=false) 
                    CommentBottomSheetDialog.show();
                
                else
                
                    Toast.makeText(mContext,"Pls Login to Continue...",Toast.LENGTH_SHORT).show();
                
            
        );

        //Gift
        gift_layout.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                if( pref.getBoolean(Variables.islogin,false)!=false) 
                    GiftBottomSheetDialog.show();
                
                else
                
                    Toast.makeText(mContext,"Pls Login to Continue...",Toast.LENGTH_SHORT).show();
                
            
        );


        //Collab
        collab_layout.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                if( pref.getBoolean(Variables.islogin,false)!=false) 
                    collabBottomSheetDialog.show();
                else
                
                    Toast.makeText(mContext,"Pls Login to Continue...",Toast.LENGTH_SHORT).show();
                

            
        );

        //Open Others Profile
        profile_lt.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                if( pref.getBoolean(Variables.islogin,false)!=false) 
                    Intent intent1 = new Intent(mContext, OthersProfileActivity.class);
                    intent1.putExtra("userID", "111805417824620727725");
                    mContext.startActivity(intent1);
                
                else
                
                    Toast.makeText(mContext,"Pls Login to Continue...",Toast.LENGTH_LONG).show();
                
            
        );



        return viewHolder;

    

    @Override
    public void onBindViewHolder(@NonNull ViewPagerAdapter.ViewHolder holder, int position) 

        MediaSource videoSource = new ExtractorMediaSource.Factory(holder.datasourceFactory
        ).createMediaSource(Uri.parse(videoDataset.get(position).getUrl()));


        holder.player.prepare(videoSource);
        holder.player.setPlayWhenReady(true);
        holder.player.setRepeatMode(Player.REPEAT_MODE_ONE);

        holder.playerView.setUseController(false);
        holder.playerView.hideController();
        holder.playerView.setShowBuffering(true);

        holder.playerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FILL);

        holder.username.setText(videoDataset.get(position).getUserid());
        holder.description.setText(videoDataset.get(position).getDescription());

    



    @Override
    public int getItemCount() 
        return videoDataset.size();
    



    public static class ViewHolder extends RecyclerView.ViewHolder 

        private PlayerView playerView;
        private SimpleExoPlayer player;
        DataSource.Factory datasourceFactory;

        TextView username;
        TextView description;



        public ViewHolder(View itemView) 
            super(itemView);

            playerView = itemView.findViewById(R.id.playerview);
            username = itemView.findViewById(R.id.username);
            description = itemView.findViewById(R.id.desc_txt);


            player = ExoPlayerFactory.newSimpleInstance(itemView.getContext(),new DefaultTrackSelector());

            playerView.setPlayer(player);



            datasourceFactory= new DefaultDataSourceFactory(itemView.getContext(),
                    Util.getUserAgent(itemView.getContext(), "videoApp"));


        
    

customviewPager.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:background="@color/black"
    android:layout_

    android:layout_
    xmlns:app="http://schemas.android.com/tools"
    app:ignore="NamespaceTypo">


    <androidx.cardview.widget.CardView
        android:id="@+id/card_view"
        android:layout_
        android:layout_

        android:padding="0dp"
        card_view:cardBackgroundColor="@color/transparent">




        <RelativeLayout
            android:layout_
            android:layout_
            android:id="@+id/mainlayout">




            <com.google.android.exoplayer2.ui.PlayerView
                android:layout_
                android:layout_
                android:id="@+id/playerview"

                app:show_buffering="when_playing"

                app:controller_layout_id="@layout/item_player_contoller"

                android:layout_gravity="center"


                app:surface_type="surface_view"

                />


        </RelativeLayout>

    </androidx.cardview.widget.CardView>



</RelativeLayout>

我想在滑动页面时释放并停止播放器。只有当前正在查看的页面应该运行 exoplayer。运行所有播放器会导致性能问题。我尝试使用 onViewDetachedFromWindow 方法释放播放器,但如果我向后滑动,我的播放器无法播放...

【问题讨论】:

【参考方案1】:

在 viewpager 片段 onresume 中再次初始化你的播放器,因为你已经释放了播放器的表面。

【讨论】:

【参考方案2】:

ViewPager 具有 callback 功能,可能对您的情况有所帮助

onPageScrolled() — 当前页面发生滚动事件时触发 onPageSelected() — 选择新页面时触发 onPageScrollStateChanged() — 当滚动状态改变时触发

您可以在选择新页面时停止旧的exoplayer 并启动新页面

【讨论】:

【参考方案3】:

覆盖 ViewpagerAdapter.java 类中的以下方法

和类viewholder函数如下图

  @Override
public void onViewDetachedFromWindow(@NonNull VideoPlayerViewHolder holder) 
    super.onViewDetachedFromWindow(holder);
    holder.pausePlayer();
    holder.releasePlayer();


@Override
public void onViewAttachedToWindow(@NonNull VideoPlayerViewHolder holder) 
    super.onViewAttachedToWindow(holder);
    holder.startPlayer();

ViewHolder 函数

public void startPlayer() 
    player.setPlayWhenReady(true);
    player.getPlaybackState();


public void pausePlayer() 
    player.setPlayWhenReady(false);
    player.getPlaybackState();


 public void releasePlayer() 
    player.setPlayWhenReady(false);
    player.release();
    player.stop(true);

如果有任何错误请告诉我..?

【讨论】:

以上是关于从 viewpager 2 停止并释放 exoplayer的主要内容,如果未能解决你的问题,请参考以下文章

即使在所有对象都已被删除和清除后,我如何才能让 R 释放并停止持有内存?

如何正确释放 AVCaptureSession

Windows系统更新缓存删除未释放空间?

stm32 uart停止释放

AHK 释放时中断循环并继续按键

在viewPager中双指缩放图片,双击缩放图片,单指拖拽图片