Android 错误“只有创建视图层次结构的原始线程才能触摸其视图”

Posted

技术标签:

【中文标题】Android 错误“只有创建视图层次结构的原始线程才能触摸其视图”【英文标题】:Android error "Only the original thread that created a view hierarchy can touch its views" 【发布时间】:2017-07-15 05:09:42 【问题描述】:

我有一个AsyncTask 和一个ProgressDialog 来显示进度。问题是我无法设置ProgressDialog Max 值,直到doInBackground 方法(我需要做一些计算),我无法在onPreExecute 方法中设置它,因为我还不知道该值。

我收到此错误,因为显然我正在尝试从背景 Thread 修改 UI

Only the original thread that created a view hierarchy can touch its views. 我在AsyncTask 构造函数中初始化ProgressDialog

public MyAsyncTask(Context context) 
    this.context = context;

    progressDialog = new ProgressDialog(context);
    progressDialog.setTitle(context.getString(R.string.wait_for_sync_title));
    progressDialog.setMessage(context.getString(R.string.please_wait));
    progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    progressDialog.setIndeterminate(true);
    progressDialog.setCancelable(false);

我在onPreExecute方法中展示它:

@Override
protected void onPreExecute() 
    super.onPreExecute();
    progressDialog.show();

我需要更新doInBackground方法中的ProgressDialog

@Override
protected void doInBackground() 
    progressDialog.setMax(myValue1);
    progressDialog.setIndeterminate(false);
    publishProgress(myValue2);

这里是onProgressUpdate 方法:

 @Override
protected void onProgressUpdate(Integer... values) 
    super.onProgressUpdate(values);
    progressDialog.setProgress(values[0]);

最后,我在 onPostExecute 方法中将其关闭:

@Override
protected void onPostExecute(Void void) 
    if(progressDialog != null) 
       progressDialog.dismiss();
    

我已经在thread 方法中尝试过这个,但我不能在AsyncTask 中这样做,因为runOnUiThreadActivity 的方法:

runOnUiThread(new Runnable() 
   @Override
   public void run() 
      progressDialog.setMax(myValue1);
      progressDialog.setIndeterminate(false);
   
);

有什么想法吗? 谢谢。

【问题讨论】:

OnProgressUpdate方法上显示进度对话框 你从哪里得到 myValue1?似乎您只是在任务开始后立即调用它,但没有指示从哪里检索值 我正在为Network Request 分页,所以在doInBackground 方法之前我不知道有多少requests。我想在progressDialog.setMax() 方法中显示的是request 的数字 也许你误解了我的意思,或者你发布的代码不完整。您在任务中做的第一件事是设置最大值,因此您必须在开始任务之前获得该值。只需在执行 AsyncTask 之前设置它 我可以知道否决票的原因吗? 【参考方案1】:

你可以得到主线程的Handler并把它贴在下面

@Override protected Void doInBackground(Void... params) 
  new Handler(Looper.getMainLooper()).post(new Runnable() 
    @Override public void run() 
      progressDialog.setMax(myValue1);
      progressDialog.setIndeterminate(false);
    
  );
  publishProgress(myValue2);

上述方法与调用runOnUiTHread()相同

【讨论】:

非常感谢,这正是我想要的 :)【参考方案2】:

我建议简单地将你的进度值设置为一对可以代表当前和最大进度的整数

@Override
protected void doInBackground() 
    publishProgress(myValue2, myValue1);


@Override
protected void onProgressUpdate(Integer... values) 
    super.onProgressUpdate(values);
    if (progressDialog.isIndeterminate())  //optional check
        progressDialog.setMax(values[1]);
        progressDialog.setIndeterminate(false);
    
    progressDialog.setProgress(values[0]);

【讨论】:

【参考方案3】:

选项 1

从 progressDialog 中获取上下文,将其转换为 Activity 并使用 runOnUiThread :

((Activity)progressDialog.getContext()).runOnUiThread(new Runnable() 
            @Override
            public void run() 
                progressDialog.setMax(myValue1);
                progressDialog.setIndeterminate(false);
            
        );

选项 2:

配置 onProgressUpdate 以设置最大值并在 doInBackground 中使用适当的值配置调用 publishProgress :

 @Override
    protected Void doInBackground(Void... voids) 
        // use this to set max
        publishProgress(null, maxValue);

        // use this to update progress
        publishProgress(progress);

        return null;
    

    @Override
    protected void onProgressUpdate(Integer... values) 
        super.onProgressUpdate(values);

        final Integer progressValue = values[0];

        if (progressValue == null) 
            // set max
            final Integer maxValue = values[1];
            progressDialog.setMax(maxValue);
            progressDialog.setIndeterminate(false);
         else 
            // update progress
            progressDialog.setProgress(progressValue);
        
    

【讨论】:

以上是关于Android 错误“只有创建视图层次结构的原始线程才能触摸其视图”的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Android Build Gradle错误配置根项目'android'?

Android Studio编译错误总结

android为啥会有以下错误?

Android Studio Android 资源链接失败错误.. AAPT:错误:找不到资源 android:attr/lStar。在 values.xml 105

无法构建 CastVideos-android,错误:路径名错误

Android 地图错误“找不到类 'android.app.AppOpsManager'”