Android 如何在UI线程外运行特定类型的任务?

Android 如何在UI线程外运行特定类型的任务?,android,multithreading,Android,Multithreading,每当recyclerview绑定视图时,我都想运行一个函数。这是一个非常长的操作,所以我必须让它远离UI线程。我知道如何创建线程,但如何使用同一个线程始终在第二个线程上运行onBindViewHolder方法的内容,而不在每次执行特定函数时创建新的线程 @Override public void onBindViewHolder (final Adapter adapter, RecyclerView.ViewHolder holder, final int position) { ne

每当
recyclerview
绑定视图时,我都想运行一个函数。这是一个非常长的操作,所以我必须让它远离UI线程。我知道如何创建线程,但如何使用同一个线程始终在第二个线程上运行
onBindViewHolder
方法的内容,而不在每次执行特定函数时创建新的线程

@Override
public void onBindViewHolder (final Adapter adapter, RecyclerView.ViewHolder holder, final int position) {
    new Thread(new Runnable() {
        @Override
        public void run () {
            theMethod(adapter, holder, position);
        }
    }).start();
}
考虑使用,然后使用HandlerThread的。当然,您必须记住在活动结束时关闭线程的步骤,否则它将无限期地停留,可能会泄漏对象

例如:

HandlerThread thread = new HandlerThread("Give Me a Name");
thread.start();
Looper looper = thread.getLooper();
Handler handler = new Handler(mServiceLooper);
// use handler to post work to the thread

这些代码行是直接从中抄袭而来的,除了在服务中,这些代码行的功能与您想要的完全相同。也许这就是你真正想用的东西

您可以通过使用来实现它。Looper的主要用途仅此而已,它使线程保持活动状态并等待新消息(可运行)

以下是官方文档中的示例代码:

class LooperThread extends Thread {
  public Handler mHandler;

  public void run() {
      Looper.prepare();

      mHandler = new Handler() {
          public void handleMessage(Message msg) {
              // process incoming messages here
          }
      };

      Looper.loop();
  }
}

现在,您可以使用处理程序向线程发布新的可运行文件(消息)。大概是这样的:

handler.post(new Runnable()
{
    public void run() {
    //This will be executed on thread using Looper.
}
});
编辑:

上面提供的方法更多的是“自己动手”。android中有一个特殊的类可以自动为您执行此操作,即。示例代码:

HandlerThread thread = new HandlerThread("name");
thread.start();
Looper looper = thread.getLooper();
Handler handler = new Handler(looper);

现在,您可以将可运行程序发布到此处理程序。

创建可以使用队列执行作业的新线程

class YourThread extends Thread {
      public List<Job> queue = new ArrayList<>();

      @Override
      public void run(){
           while(queue.size() == 0)
               wait(); // nothing to do, wait...
           Job job = queue.get(queue.size() - 1); // pop queue
           queue.remove(queue.size() - 1);
           dosomething(job);

      }

      public void addJob(....){
           ...
           queue.add(job, 0);
      }
}

你能详细说明一下“在第二个线程上运行,而不是每次都创建一个线程”吗?如果我错了,请纠正我,但由于onBindViewHolder被调用了多次,OP希望在同一个线程上运行其代码的所有实例,而不是每次都创建一个新实例。
ExecutorService。newSingleThreadExecutor
可用于线程管理。但是我担心这种方法,为什么需要在
onBindViewHolder
方法中执行一些线程呢?您需要记住,在完成任务后,由于滚动,某些位置上对holder的引用可能无效。ViewHolder包含图像,我会在第二个线程上生成调色板,因为如果我在主线程上创建调色板,会减慢应用程序的速度。如果你知道一个更好的方法,那么请让我知道。很抱歉这么长时间的延迟,我不确定你的用例。你试过使用吗?
YourThread thread = new ...
thread.start()

@Override
public void onBindViewHolder (final Adapter adapter, RecyclerView.ViewHolder holder, final int position) {
     thread.addJob(...);
     // remember that after the job finished, the item may be recycled
}