【问题标题】:Forcing runOnUiThread强制 runOnUiThread
【发布时间】:2021-11-25 19:55:13
【问题描述】:

我正在尝试强制后台线程发布进度,例如 AsyncTask,但我失败得很惨。我不明白为什么它不起作用。

我这样开始后台线程:

new Thread(() -> {
    doInBackground();
}).start();

doInBackground() 内部,我有一个这样的循环:

...
synchronized (this) {
    ...
    for (int i = 0; i < 100000; i++) {
        ...
        if (i % 100 == 0) {
           System.out.println("### INNER ### ");
           activity.runOnUiThread(this::onProgressUpdate);
        }
    }
 }

onProgressUpdate() 很简单

onProgressUpdate() {
     System.out.println("-------------");
}

我期望的是,对于每个### INNER ### ,我都会看到一个插入的-------------。然而,我首先看到所有### INNER ### ,然后是所有-------------。所以这条线

activity.runOnUiThread(this::onProgressUpdate);

在我想要的那一刻没有被执行。我尝试在各处添加和删除几个synchronized (this),但没有成功。

我做错了什么?

【问题讨论】:

  • IMO 这是一个正确的行为,输出取决于线程的执行。两种印刷品都以不同的线印刷。这就是为什么您看不到顺序执行的原因。当您向 UI 线程发布内容时,您当前的线程是空闲的并执行下一个 print ("### INNER ###) 语句。
  • 我明白了。那么,如何解决这个问题呢?
  • 您已经在 UI 线程上更新进度。确切的问题是什么?你永远无法确定主线程什么时候会执行你的runnable。
  • 对不起,我以为我说得够清楚了。确切的问题是线程标题中的问题:强制runOnUiThread 获取### INNER ###,然后是-------------,然后是### INNER ###,然后是-------------,依此类推。您的回答似乎是,除非我在同一个线程中执行所有操作(因此在执行 doInBackground 任务时阻止它),否则这是不可能的。但是,AsyncTask 中的publishProgress 方法是如何执行此操作的呢?
  • AsyncTask 在内部执行与您的代码非常相似的操作。它将作业发布到主处理程序上,该处理程序将作业传递到主 UI 线程。在此期间,异步操作永远不会受到干扰。您可以尝试类似 ``` val semaphore = Semaphore(1) val mainHandler = Handler(Looper.getMainLooper()) for (your logic) { try { semaphore.acquire() mainHandler.post { /* do your main ui work*/ semaphore.release() } } catch (e: Exception) {} } ```

标签: java android multithreading synchronization background-process


【解决方案1】:

也许您可以为您的用例尝试以下类似的方法。

  val semaphore = Semaphore(1)
        val mainHandler = Handler(Looper.getMainLooper())
        for (your logic) {
            try {
                semaphore.acquire()
                mainHandler.post {
                    /* do your main ui work*/
                    semaphore.release()
                }
            } catch (e: Exception) {

            } 
        }
        

【讨论】:

  • 这行得通。信号量停止后台线程的执行。谢谢你指点我Semaphore,我不知道。
猜你喜欢
  • 1970-01-01
  • 2015-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-20
  • 2012-04-17
  • 2013-05-01
相关资源
最近更新 更多