Android 错误 "Only the original thread that created a view hierarchy can touch its views"
Android error "Only the original thread that created a view hierarchy can touch its views"
我有一个 AsyncTask
和一个 ProgressDialog
来显示进度。问题是我在doInBackground
方法之前无法设置ProgressDialog Max
值(我需要做一些计算),我无法在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
中这样做,因为 runOnUiThread
是 Activity
的一种方法:
runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.setMax(myValue1);
progressDialog.setIndeterminate(false);
}
});
有什么想法吗?
谢谢。
我建议简单地让你的进度值是一对可以代表当前和最大进度的整数
@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
从 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);
}
}
您可以获取主线程的 Handler
和 post 如下所示
@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()
我有一个 AsyncTask
和一个 ProgressDialog
来显示进度。问题是我在doInBackground
方法之前无法设置ProgressDialog Max
值(我需要做一些计算),我无法在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
中这样做,因为 runOnUiThread
是 Activity
的一种方法:
runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.setMax(myValue1);
progressDialog.setIndeterminate(false);
}
});
有什么想法吗? 谢谢。
我建议简单地让你的进度值是一对可以代表当前和最大进度的整数
@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
从 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);
}
}
您可以获取主线程的 Handler
和 post 如下所示
@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()