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

时间:2017-02-24 11:25:24

标签: android multithreading android-asynctask progressdialog

我有AsyncTask ProgressDialog来显示进度。问题是我无法在ProgressDialog Max方法之前设置doInBackground值(我需要进行一些计算),我无法在onPreExecute方法中设置它,因为我不知道它的值爱好。

我收到此错误,因为很明显我试图从后台UI修改Thread

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

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();
}

我需要更新ProgressDialog方法中的doInBackground

@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);
   }
});

有什么想法吗? 感谢。

3 个答案:

答案 0 :(得分:1)

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

@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]);
}

答案 1 :(得分:1)

选项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);
        }
    }

答案 2 :(得分: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()

相同