【问题标题】:android.view.ViewRootImpl$CalledFromWrongThreadExceptionandroid.view.ViewRootImpl$CalledFromWrongThreadException
【发布时间】:2014-02-25 13:44:10
【问题描述】:

我在列表视图中显示了网页下载百分比的进度条。

for(int i=0;i< 5;i++)
        {
            new UploadTask(i).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "http://www.google.com");
        }

我的上传任务

public class UploadTask extends AsyncTask<String, Void, String>
    {
        int id;
        public UploadTask(int id) {
            this.id = id;
        }
        @Override
        protected String doInBackground(String... params) {
            try {
                return HttpUrlConnection.getContentFromUrl(params[0], listener);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                return "";
            }
        }
        HttpListener listener = new HttpListener() {

            @Override
            public void processCompletion(int x) {
                publishProgress(x);
            }
        };
        public void publishProgress(Integer... ints) {
            progressLevelList.set(id, ints[0]);
            uploadAdapter.notifyDataSetChanged();
        }
    }

但是当我通知适配器时出现以下错误。

java.lang.RuntimeException: An error occured while executing doInBackground()

    Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

如何解决这个错误?

【问题讨论】:

    标签: android


    【解决方案1】:

    您不能在后台线程上更改 UI。尝试使用onProgressUpdate(Object... values) AsyncTask 方法,它在UI线程上触发。

    @Override
    protected void onPreExecute() {
      super.onPreExecute();
      //do you bg work here
    
      publishProgress(null);
    
      //do you bg work here
    }
    
    @Override
    protected void onProgressUpdate(Void... values) {
     super.onProgressUpdate(values);
     //update UI here
    }
    

    您的代码应如下所示:

      public class UploadTask extends AsyncTask<String, Integer, String>
        {
            int id;
            public UploadTask(int id) {
                this.id = id;
            }
            @Override
            protected String doInBackground(String... params) {
                try {
                    return HttpUrlConnection.getContentFromUrl(params[0], listener);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    return "";
                }
            }
            HttpListener listener = new HttpListener() {
    
                @Override
                public void processCompletion(int x) {
                    publishProgress(x);
                }
            };
    
            @Override
            protected void onProgressUpdate(Integer... values) {
                progressLevelList.set(id, ints[0]);
                uploadAdapter.notifyDataSetChanged();
            }
    
        }
    

    【讨论】:

      【解决方案2】:

      您不应该覆盖 publishProgress() - 您应该覆盖 onProgressUpdate(),它从 publishProgress() 接收数据,但在 UI 线程上运行。

      请注意,当前您的 AsyncTask 定义不正确。你的输入和输出确实都是String,但是你的进度更新是Integer,这意味着你应该扩展AsyncTask&lt;String, Integer, String&gt;

      【讨论】:

        【解决方案3】:

        更改AsyncTask&lt;String, Integer, String&gt;而不是AsyncTask&lt;String, Void, String&gt;

        改变

        @Override
            public void onProgressUpdate(Integer... ints) {
                    progressLevelList.set(id, ints[0]);
                    uploadAdapter.notifyDataSetChanged();
                }
        

        而不是

        public void publishProgress(Integer... ints) {
                    progressLevelList.set(id, ints[0]);
                    uploadAdapter.notifyDataSetChanged();
                }
        

        【讨论】:

          【解决方案4】:

          我们只能从通常称为 UI 线程的主线程更改 UI。我们无法更改后台线程上的 UI。你应该重写 onProgressUpdate(),它从 publishProgress() 接收数据,但在 UI 线程上运行。

          【讨论】:

            猜你喜欢
            • 2023-03-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-06-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多