当 RecyclerView 滚动时,从 ThreadPool 中杀死正在运行的线程

Posted

技术标签:

【中文标题】当 RecyclerView 滚动时,从 ThreadPool 中杀死正在运行的线程【英文标题】:Kill Running Threads from ThreadPool When the RecyclerView Scrolls 【发布时间】:2018-01-05 22:16:47 【问题描述】:

我有ThreadPool,它从远程网址获取视频缩略图。我在RecyclerView 中显示此缩略图,ThreadPool 按预期工作。我从onBindViewHolderRecyclerView Adapter 开始这项任务。问题是,假设如果我有 100 个任务,并且向下滚动到第 100 个项目(最后一个),那么线程必须等到必须处理 99 个。所以我需要的是当用户滚动时我必须取消其他不需要在屏幕上显示的任务,并且应该启动新任务。我该怎么做,任何帮助将不胜感激。

线程池类

public static VideoThumbnailThreadPoolManager getInstance() 

public void downloadThumbnail(String url, DownloadCompleteListener listener) 
        mExecutor.execute(new ImageDownloaderThread(url, listener));
  


 private class ImageDownloaderThread extends Thread 
        String mUrl;
        DownloadCompleteListener mListener;

        ImageDownloaderThread(String url, DownloadCompleteListener listener) 
            setName(url);
            mUrl = url;
            mListener = listener;
        

        @Override
        public void run() 
            try 
                Bitmap thumbnail = GeneralUtils.retriveVideoFrameFromVideo(mUrl);
                if (mListener != null) 
                    mListener.onThumbnailDownloaded(thumbnail);
                
             catch (Throwable throwable) 
                throwable.printStackTrace();

                if (mListener != null) 
                    mListener.onThumbnailDownloaded(null);
                
            
        
    

public void killThreadBy(String name) 
    //Give you set of Threads
    Set<Thread> setOfThread = Thread.getAllStackTraces().keySet();

    //Iterate over set to find yours
    for (Thread thread : setOfThread) 
        if (thread.getName().equals(name)) 
            thread.interrupt();
        
    



编辑

我没有得到缩略图网址,我正在通过拍摄视频的第一帧来生成缩略图。

注意

不推荐 Picasso、Glide...,因为它无法从远程视频 url 加载缩略图。

【问题讨论】:

您可以使用 Picasso,它与 recyclerView 配合得非常好(它可以完全按照您的需要管理图像下载) 我没有图片网址,我正在从视频网址生成缩略图,所以毕加索,滑翔不会有帮助 那么你从 web api 收到了什么?如果不是位图,那是什么? 它是一个视频,我正在拍摄该视频的第一帧并将其显示为缩略图 发送?我没有发送任何内容,我只是从位于服务器中的视频中获取一帧。 【参考方案1】:

我已经得到了答案。

我在 onViewRecycled() 方法调用时移除任务,

     @Override
     public void onViewRecycled(RecyclerView.ViewHolder holder) 
      if (holder instanceof MyViewHolder) 
                MyViewHolder viewHolder = (MyViewHolder) holder;
        String threadName = holder.itemView.getTag();

        if(notEmpty(threadName))
          executor.remove(getRunnableFromName(threadName));
        
       
   

【讨论】:

只需在onBindViewHolder 中使用submit(Runnable task) 并将Futore 存储在一些ViewHolder 字段中,如holder.future = tpe.submit(...)onViewRecycled,只需调用holder.future.cancel(),仅此而已 你能解释更多吗?如果可以的话,添加更多代码 解释什么?在Holder 中添加字段Future future,在onBindViewHolder 中调用submit(..),在onViewRecycled 中调用holder.future.cancel() 会检查。 :) 您能分享您的完整答案吗?我们如何删除可运行对象或线程?

以上是关于当 RecyclerView 滚动时,从 ThreadPool 中杀死正在运行的线程的主要内容,如果未能解决你的问题,请参考以下文章

Recyclerview 在滚动期间更改项目

RecyclerView在刷新时滚动时崩溃

应用程序在 recyclerview 滚动 android kotlin 时崩溃

当nestedscrollview 中的recyclerview 滚动时,对讲焦点转到工具栏项

如何使用 JSON API 在滚动时在 recyclerview 中加载更多数据

单击项目Android时RecyclerView滚动