在 doInBackground 中的 AsyncTask 中更改 UI 线程的视图,CalledFromWrongThreadException 并不总是抛出



AsycnTask中的以下代码:

@Override
protected Boolean doInBackground(View... params) {
try{
Drawable drawPhoto = DataDatero.ImageDownload(taskPhotoName);
((ImageView)params[0]).setImageDrawable(drawPhoto);
((TextView)params[1]).setText(taskItemListText);
((TextView)params[2]).setTextColor(taskColore);
((TextView)params[2]).setText(taskItemStockText);
[...]
}

抛出CalledFromWrongThreadException,描述为:

只有创建视图层次结构的原始线程才能触及其查看

这已经在很多问题中进行了讨论:例如,另一个例子;并得出相同的结论。

但我得到的不仅仅是异常

我从List适配器中的getView调用执行,并且在为文本抛出异常时,在视图中更新图像(params[0])。此外,如果我只保留textview更新,那么文本将被更新,并且不会引发异常。

如果我先更新TextView,然后更新ImageView,一些文本和图像会更新,而一些图像不会更新(该imageDownload包括2-3秒的网络操作)

为什么有些更新了,而另一些没有

注意:这只在api 16仿真上使用sdk 4.0 v4支持进行了测试。我修复了它,我不会触及doInBackground中的视图第二个例子是类似的。。。如果onCreate没有完成,操作是否会得到验证

我遇到了一个类似的问题,并在这里提出了一个问题(经过大量挖掘后自行回答)。

本质上,它可以归结为,与每个人的想法相反,如果这些视图还没有经过布局遍历,则可以AsyncTaskexecute()修改UI元素。这与主执行流(活动生命周期方法/回调)异步发生,因此,如果有问题的View是在调用execute()之前不久创建的,则可以访问它们(这意味着没有抛出异常,当然这仍然是非常糟糕的做法,也是不可取的)。因为execute()发生在另一个线程上,所以布局遍历(在UI线程上运行)可能会在execute()运行时完成,这解释了为什么只有一些视图可以被修改,而其他视图则抛出异常。它还解释了为什么"只保留文本视图更新"(并可能删除ImageView更新)会导致这些更新也"神奇地"工作。由于这是一个与时间相关的问题,它取决于许多因素,其中包括Drawable drawPhoto = DataDatero.ImageDownload(taskPhotoName);运行所需的时间。

附言:我意识到这是一个迟来的答案,但我认为这对首先找到答案的人来说是有用的,没有多少帖子涉及这样的问题。

异常非常清楚。不能从不同于UI Thread的线程更新UI元素。doInBackground在不同线程中执行代码

为什么不能将更新UI的信息传递给onPostExecute方法?这就是UI要更新的地方。

运行任务的execute方法时,doInBackground方法在后台线程中执行。

并且您不允许从后台线程修改UI。

因此,不要修改doInBackground方法中的UI。

您应该在onPostExecute方法中执行这些UI内容,因为它保证在UI线程中执行。

相关内容

  • 没有找到相关文章

最新更新