不应用默认 AsyncTask 线程优先级 (BACKGROUND)

Default AsyncTask thread priority (BACKGROUND) is not applied

在默认的异步任务构造函数源代码中,我们有以下代码,它将线程优先级设置为 Process.THREAD_PRIORITY_BACKGROUND = 10

  mWorker = new WorkerRunnable<Params, Result>() {
        public Result call() throws Exception {
            mTaskInvoked.set(true);
            Result result = null;
            try {
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                //noinspection unchecked
                result = doInBackground(mParams);
                Binder.flushPendingCommands();
            } catch (Throwable tr) {
                mCancelled.set(true);
                throw tr;
            } finally {
                postResult(result);
            }
            return result;
        }
    };

我创建了一个示例应用程序,我在其中创建了简单的异步任务,并在 doInBackground() 中通过

记录了线程优先级

Log.d("@@@ AsyncTask", "Thread name = " + Thread.currentThread().getName() + "Tread priority " + Thread.currentThread().getPriority());

预期结果: com.example.myapplication D/@@@ AsyncTask: Thread name = AsyncTask #1Tread priority 10

实际结果: com.example.myapplication D/@@@ AsyncTask: Thread name = AsyncTask #1Tread priority 5

后台线程的线程优先级与主线程优先级相同 com.example.myapplication D/@@@ MainActivity onCreate: Thread name = mainTread priority 5

我在 API 19 和 API 26 上测试过这个。结果是一样的。

为什么异步任务没有应用后台线程优先级? 还是我阅读优先级的方法不对?

我可以上传资源到github,但是没有太多可以上传的。只有 AsyncTask 和日志语句。

来自 Process.setThreadPriority 的 javadoc:

Set the priority of the calling thread

AsyncTask.execute() 方法在默认 Executor 中执行 AsyncTask.doInBackground()Executor 管理线程池并允许您将任务提交给其中一个线程。为 Executor 创建线程的 class 是 ThreadFactory。您需要在 ExecutorThreadFactory 上执行,以创建具有所需优先级的线程。

class PriorityThreadFactory(
  namePrefix: String,
  private val threadPriority: Int = Thread.NORM_PRIORITY
) : ThreadFactory {

  private val group: ThreadGroup = System.getSecurityManager()?.threadGroup ?: Thread.currentThread().threadGroup
  private val threadNumber = AtomicInteger(1)
  private val namePrefix: String = "pool-$namePrefix-thread-"

  override fun newThread(r: Runnable): Thread {
    val t = Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0)
    if (t.isDaemon) {
      t.isDaemon = false
    }
    if (t.priority != threadPriority) {
      t.priority = threadPriority
    }
    return t
  }
}

因此,当您执行 AsyncTask 时,您将传递使用 PriorityThreadFactory.

Executor
  val executor = Executors.newSingleThreadExecutor(PriorityThreadFactory("asynctask", Process.THREAD_PRIORITY_BACKGROUND)
  asyncTask.executeOnExecutor(executor)

原来我获取线程优先级的方法是错误的。

获得线程优先级的正确方法是Process.getThreadPriority(Process.myTid())