方法 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) 方法是不是在离线模式下工作?

如何从 R 中的 xlsx 文件中检测“删除线”样式

怎么从Auto CAD中提取多段线坐标?