方法 publishProgress 必须从工作线程调用,目前推断线程为主线程
Posted
技术标签:
【中文标题】方法 publishProgress 必须从工作线程调用,目前推断线程为主线程【英文标题】:Method publishProgress must be called from the worker thread, currently inferred thread is main thread 【发布时间】:2019-11-23 22:34:42 【问题描述】:我最近将一个完美的 android 项目重新导入到 Android Studio 中,它单方面决定抱怨绝对安全的代码(并且在 squiggle 下红色)。
我每次都会在 IDE 中看到这个红色曲线(但仅限于 postExecute
):
方法
publishProgress
必须从工作线程调用,目前推断线程为主线程
private void triggerClick()
final class LoginHttpTask
extends
AsyncTask<String/* Param */, Boolean /* Progress */, String /* Result */>
@Override
protected String doInBackground(String... params)
publishProgress(true);
@Override
protected void onPostExecute(String checkphpResponse)
publishProgress(false);
new LoginHttpTask.execute();
是什么原因,为什么代码运行得很好?
【问题讨论】:
【参考方案1】:这是一个 linting 问题。来自publishProgress(Params...)
的文档(我的粗体):
当后台计算仍在运行时,可以从
doInBackground(Params...)
调用此方法以在 UI 线程上发布更新。
所以这个方法被设计成只在后台线程上调用,这体现在带有@WorkerThread
注解的方法的in the source:
@WorkerThread
protected final void publishProgress(Progress... values)
if (!isCancelled())
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
因此,doInBackground(String...)
在后台线程上运行时,onPostExecute(String checkPhpResponse)
在 UI 线程上运行,因为您打算直接在该回调中更新您的 UI。因为publishProgress(Params...)
被注释为@WorkerThread
,所以即使代码可以编译,IDE 也会抛出错误——它可以工作,但这是不好的做法。
没有任何关于如何使用AsyncTask
的进一步上下文,我无法建议如何更新您的代码,但我建议避免使用publishProgress(boolean)
,而是直接从@987654333 中更新您的用户界面@
【讨论】:
所以答案是remove it
:D 老实说这段代码是SO OLD
现在我真的是在F2'ing 整个事情并整理它。我通常不使用publishProgress
之类的东西,我更喜欢自己展示这些东西,所以我不知道它在里面做什么
老实说,我还认为onPostExecute
被分派到 UI 线程而不是在其上运行,这似乎是一种糟糕的编写方式
@MrHeelis 根据我的猜测,这是为了简化进行后台调用的过程,例如一个网络请求。将其关闭,然后您可以在完成后直接更新 UI。不过,这是从 Android 的早期阶段开始的,有很多事情现在由于事后诸葛亮而没有多大意义......以上是关于方法 publishProgress 必须从工作线程调用,目前推断线程为主线程的主要内容,如果未能解决你的问题,请参考以下文章
在 GZIP 解压过程中设置 ProgressBar maxValue 和 publishProgress 值
为啥在循环内调用 publishProgress 并多次调用(没有循环)会显示不同的行为?
reverseGeocodeLocation(_ location: CLLocation) 方法是不是在离线模式下工作?