2

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 updates ,则文本会更新并且不会引发异常。

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

为什么有的更新了,有的没更新?

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

4

4 回答 4

3

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

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

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

于 2015-05-21T12:01:45.153 回答
0

例外很明显。您不能UI从不同于UI Thread. doInBackground在不同的线程中执行代码

于 2012-12-14T16:42:23.127 回答
0

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

于 2012-12-14T16:43:13.440 回答
0

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

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

所以,不要在doInBackground方法中修改 UI。

你应该在onPostExecute方法中做这些 UI 的东西,保证在 UI 线程中执行。

于 2012-12-14T16:43:40.283 回答