Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android runOnUiThread/AsyncTask无法解析CalledFromErrorThreadException_Android_Multithreading_Android Asynctask_Handler - Fatal编程技术网

Android runOnUiThread/AsyncTask无法解析CalledFromErrorThreadException

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

我正在为Android应用程序工作,并通过使用AsyncTask类实现ProgressBar

问题在于,在某些设备上,它会导致onPostExecute中的“CalledFromErrorThreadException:只有创建视图层次结构的原始线程才能接触其视图”。在这些设备上,问题100%发生。在其他设备上,它工作正常

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(进度…)
  • 该任务只能执行一次(如果尝试第二次执行,将引发异常)
您不会显示通常实例化和执行任务的位置,因此请确保在UI/主线程上已有的代码中执行此操作。请注意,上面的第一个要点可能解释了为什么这适用于某些设备,而不适用于其他设备

创建视图层次结构 信息告诉你

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

您假设这是因为您的异步任务(奇怪地)试图在后台线程上修改UI。但是,您可能会遇到此错误,因为异步任务修改了主线程上的UI,但UI(
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");