【问题标题】:Only the original thread that created a view hierarchy can touch its views.onProgressUpdate只有创建视图层次结构的原始线程才能访问其views.onProgressUpdate
【发布时间】:2013-09-03 10:49:53
【问题描述】:

从 Android 4.0 开始我遇到了问题(在 2.3.6 上它正在工作)。

onProgressUpdate 它应该已经在 UI 线程中。 我试过activity.runOnUiThread 现在是Handler 版本,ofc 首先是没有任何 tham。如何解决?

public class ReadDataTask extends AsyncTask<String, String, JSONArray> {

    private Activity activity;
    protected ProgressDialog dlg;

    private long startRead, endRead, endJson;

    public ReadDataTask(Activity activity) {
        this.activity = activity;
        dlg = new ProgressDialog(activity);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        dlg.show();
        startRead = System.currentTimeMillis();
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
        if (values != null && values.length > 0) {
            final String msg = values[0];
            new Handler().post(new Runnable() {
                public void run() {
                    dlg.setMessage(msg);// android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
                }
            });
        }
    }


    @Override
    protected JSONArray doInBackground(String... params) {
           ... long task here
           publishProgress("Converting to JSON: " + (1 + i) + " / " + dataList.size());

【问题讨论】:

  • 请发布您的堆栈跟踪。
  • @CommonsWare 更新了屏幕截图,并且在源代码中标记了代码行,发生在哪里。移动了 dlg = new ProgressDialog(activity);到 onPreExecute() 仍然有错误
  • 删除Handler 的东西,然后在onProgressUpdate() 中直接调用dlg.setMessage() 重试。如果您遇到相同的异常,请发布 complete 堆栈跟踪。为此,您可以突出显示这些行,将它们复制到剪贴板(例如,Ctrl-C),然后将它们粘贴到此处并格式化为源代码。在不相关的注释中,删除您的 activity 数据成员,因为您可能在构造函数之外使用它的唯一位置是 doInBackground(),这是您应该引用活动,由于配置更改。

标签: android multithreading android-asynctask


【解决方案1】:

仅在onPreExecute() 中创建一次处理程序,该处理程序从 UI 线程调用并保存对它的引用,而不是在 onProgressUpdate() 中发布到它。

处理程序发布到创建它的线程。

【讨论】:

    【解决方案2】:

    谢谢大家! 解决方案的实现:

    private Activity activity;
    protected ProgressDialog dlg;
    private Handler myHandler;
    
    private long startRead, endRead, endJson;
    
    public ReadDataTask(Activity activity) {
        this.activity = activity;
    }
    
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    
        myHandler = new Handler();
    
        dlg = new ProgressDialog(activity);
        dlg.show();
        startRead = System.currentTimeMillis();
    }
    
    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
        if (values != null && values.length > 0) {
            final String msg = values[0];
            myHandler.post(new Runnable() {
                public void run() {
                    dlg.setMessage(msg);
                }
            });
        }
    }
    

    【讨论】:

      【解决方案3】:

      以下内容对我有用。

      myHandler.post(new Runnable() {
                  public void run() {
                      dlg.setMessage(msg);
                  }
              });
      

      【讨论】:

        猜你喜欢
        • 2012-12-26
        • 1970-01-01
        • 1970-01-01
        • 2018-05-30
        • 2016-01-17
        • 1970-01-01
        • 2015-05-22
        相关资源
        最近更新 更多