Android runOnUiThread/AsyncTask无法解析CalledFromErrorThreadException
我正在为Android应用程序工作,并通过使用AsyncTask类实现ProgressBar 问题在于,在某些设备上,它会导致onPostExecute中的“CalledFromErrorThreadException:只有创建视图层次结构的原始线程才能接触其视图”。在这些设备上,问题100%发生。在其他设备上,它工作正常Android runOnUiThread/AsyncTask无法解析CalledFromErrorThreadException,android,multithreading,android-asynctask,handler,Android,Multithreading,Android Asynctask,Handler,我正在为Android应用程序工作,并通过使用AsyncTask类实现ProgressBar 问题在于,在某些设备上,它会导致onPostExecute中的“CalledFromErrorThreadException:只有创建视图层次结构的原始线程才能接触其视图”。在这些设备上,问题100%发生。在其他设备上,它工作正常 public final class MyAsyncTask extends AsyncTask<String, Integer, String> { p
public final class MyAsyncTask extends AsyncTask<String, Integer, String>
{
private ProgressBar progress;
private ListActivity activity;
public MyAsyncTask(ListActivity activity, ProgressBar progress)
{
this.progress = progress;
this.activity = activity;
}
protected void onPreExecute()
{
this.progress.setVisibility(view.VISIBLE);
}
protected String doInBackground(String[] arg0)
{
// getting xml via httpClient
return string;
}
protected void onPostExecute(String result)
{
this.progress.setVisibility(view.GONE);
}
即使这样也没有解决问题。同样的异常仍然发生
从日志中,我确认Thread.currentThread().getId()肯定不同于处理程序中应用程序的主活动线程
我卡住了。如有任何建议,将不胜感激
注意:我编辑了上面的示例代码(不是真正的代码),以修复错误的方法名称和缺少的“返回字符串”。
稍后我将添加更多信息。在UI线程中编写一个处理程序,并从onPostExecute调用该处理程序。这将解决问题 像这样的。在UI线程(主线程)中具有处理程序: 并按如下方式调用onPostExecute():
handler.sendEmptyMessage(MSG);
我看不出MyAsyncTask本身有任何问题,但仍有其他问题可能出现 启动异步任务 从 线程规则 这个类必须遵循一些线程规则 要正常工作:
- 必须在UI线程上加载AsyncTask类。这是自动完成作为果冻豆
- 必须在UI线程上创建任务实例
- 必须在UI线程上调用execute(参数…)
- 不要手动调用onPreExecute()、onPostExecute(结果)、doInBackground(参数…)和onProgressUpdate(进度…)
- 该任务只能执行一次(如果尝试第二次执行,将引发异常)
ProgressBar
)最初没有正确创建
例如,您如何在错误的线程(主线程以外的任何线程)上错误地创建视图,并获得相同的错误
更多
但是,我希望确切地看到您在哪里记录线程ID,以及您得到的值。如果您查看我的前两个建议,但它们不能解决您的问题,那么我们可能需要更多信息
您还提到了(?),但没有说明如何或在何处使用它。通常,使用AsyncTask
就不需要使用Handler
,所以我有点担心您可能会如何使用它
更新
根据下面评论中的讨论,这里的问题似乎是。一些可能在后台线程上运行的代码首先导致加载AsyncTask
类。AsyncTask
的原始(pre-jellybean)实现要求在主线程上加载类(如上面的线程规则所述)。简单的解决方法是在主线程上添加代码(例如在应用程序#onCreate()
),强制执行异步任务的早期确定性类加载:
Class.forName("android.os.AsyncTask");
确保仅从主线程调用AYSNTASK.execute()。是否尝试删除@Override?有时我删除它,问题就解决了。为什么你在另一个线程中运行一个线程!!!异步任务是线程管理的,它不阻塞代码。删除runOnUiThread块并只执行异步任务。这是什么doSomethingInBackground()
以及doInBackground()在哪里?另外,在doInBackground()
@MuhammadBabar中发布您正在调用的代码,我假设该方法是伪代码,而不是他们所使用的。显然,该代码甚至不会编译,因为该方法中没有return
语句(返回String
),而且doInBackground()
是抽象的。@Moh.Sukhni我认为这也很奇怪,MyAsyncTask应该可以工作,但由于它不能工作,我正在尝试其他一些技巧,比如使用rununuithread。onPostExecute()
应该已经在主线程上运行,因此如果此解决方案确实解决了问题,那么其他问题就错了AsyncTask
应该不再需要使用Handler
对象。AsyncTask只不过是由系统维护的线程。因此,在某些手机上,可能是由于框架代码的更改或定制而导致的同步或计时错误。一些原始设备制造商甚至更改了框架中的线程逻辑以提高效率。所以这可能是它的副作用。你最好使用能保证事情正常运行的处理器:)我完全不同意。您是否有参考资料支持您的说法,即OEM已将AsyncTask修改为在非主线程上运行onPostExecute()
(如果任务是在主线程上启动的)?“那将是一个非常大的错误。”内特.“。。我说这可能是一个错误或副作用。我并没有说他们想在非主线程上运行onPostExecute()。我不能给你参考,但是做了很多定制。我是一名框架工程师,在三星工作了很长时间。如果这是一个bug,那么Handler
也可能无法正常工作(啊哈!)。在任何情况下,当出现这样的问题时,我怀疑的可能性要高出100倍
handler.sendEmptyMessage(MSG);
Class.forName("android.os.AsyncTask");