在 Android 上将 ProgressDialog 与 Thread 一起使用会引发 ViewRoot$CalledWrongFromThreadException
我试图在填充布局时显示进度对话框:
编辑(这是代码):
public class CalendarMonth extends Activity {
private ProgressDialog mDialog;
private int mMonth = 0;
private int mYear = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.calendar_m);
filterData();
}
private void filterData() {
mDialog = ProgressDialog.show(this, "Loading calendar",
"Please wait...", true, true);
mDialog.setCancelable(false);
mDialog.show();
new GenerateMonth().execute();
}
class GenerateMonth extends AsyncTask {
protected Object doInBackground(Object... arg0) {
generateMonth();
return true;
}
protected void onPostExecute(Object result) {
mDialog.dismiss();
}
private void generateMonth() {
mCalendar = new CalendarInstance(mMonth, mYear);
mMonth = this.mCalendar.getSelectedMonth();
mYear = this.mCalendar.getSelectedYear();
TextView monthName = (TextView) findViewById(R.id.monthName);
monthName.setText(mCalendar.getMonthAndYearAsString());
Button monthPrevious = (Button) findViewById(R.id.monthPrevious);
monthPrevious.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int month = mMonth - 1;
int year = mYear;
if (mMonth == 1) {
month = 12;
year = mYear - 1;
}
mMonth = month;
mYear = year;
filterData();
}
});
Button monthNext = (Button) findViewById(R.id.monthNext);
monthNext.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int month = mMonth + 1;
int year = mYear;
if (mMonth == 12) {
month = 1;
year = mYear + 1;
}
mMonth = month;
mYear = year;
filterData();
}
});
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setNumColumns(7);
gridview.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
gridview.setBackgroundColor(Color.BLACK);
gridview.setAdapter(new CalendarMonthAdapter(this, mMonth, mYear));
}
@Override
protected void onResume() {
super.onResume();
filterData();
}
}
I'm trying to show Progress Dialog while filling layout:
EDIT (here is the code):
public class CalendarMonth extends Activity {
private ProgressDialog mDialog;
private int mMonth = 0;
private int mYear = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.calendar_m);
filterData();
}
private void filterData() {
mDialog = ProgressDialog.show(this, "Loading calendar",
"Please wait...", true, true);
mDialog.setCancelable(false);
mDialog.show();
new GenerateMonth().execute();
}
class GenerateMonth extends AsyncTask {
protected Object doInBackground(Object... arg0) {
generateMonth();
return true;
}
protected void onPostExecute(Object result) {
mDialog.dismiss();
}
private void generateMonth() {
mCalendar = new CalendarInstance(mMonth, mYear);
mMonth = this.mCalendar.getSelectedMonth();
mYear = this.mCalendar.getSelectedYear();
TextView monthName = (TextView) findViewById(R.id.monthName);
monthName.setText(mCalendar.getMonthAndYearAsString());
Button monthPrevious = (Button) findViewById(R.id.monthPrevious);
monthPrevious.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int month = mMonth - 1;
int year = mYear;
if (mMonth == 1) {
month = 12;
year = mYear - 1;
}
mMonth = month;
mYear = year;
filterData();
}
});
Button monthNext = (Button) findViewById(R.id.monthNext);
monthNext.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int month = mMonth + 1;
int year = mYear;
if (mMonth == 12) {
month = 1;
year = mYear + 1;
}
mMonth = month;
mYear = year;
filterData();
}
});
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setNumColumns(7);
gridview.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
gridview.setBackgroundColor(Color.BLACK);
gridview.setAdapter(new CalendarMonthAdapter(this, mMonth, mYear));
}
@Override
protected void onResume() {
super.onResume();
filterData();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用 AsyncTask 可能更容易 http://developer.android.com/reference /android/os/AsyncTask.html
所以你会有类似这样的
编辑下面
这样做
it might be easier to use an AsyncTask http://developer.android.com/reference/android/os/AsyncTask.html
so you would have something like this
EDIT BELOW
do it like this
该错误必须出现在filterData 中,如果您从过滤器数据更新UI,则会出现该异常。我建议使用异步任务,使用 doInBackground 构建数据,并使用 onPostExecute 更新 UI。
The error must be in filterData, if you are updating the UI from filter data it will give that exception. I would recomend using async task, using doInBackground to build the data, and onPostExecute to update the UI.
看来您的问题出在generateMonth函数中,该函数是从doInBackground函数调用的。您不应该从 doInBackground 函数或从 doInBackground 调用的任何函数访问 UI。此函数旨在执行需要大量时间的任务,例如计算或复杂的数据库查询,但不得访问 UI。您的 UI 更新应在 onPostExecute 函数中完成。所以,像这样的事情:
doInBackground(或从那里调用的generateMonth)中不允许使用
It seems that your problem is in generateMonth function, which is invoked from the doInBackground function. You should not access UI from doInBackground function or from any function called from doInBackground. This function is aimed to do tasks that require lot of time, like calculations or complex DB queries, but MUST NOT access UI. Your UI updates should be done in function onPostExecute. So, things like:
are not allowed in doInBackground (or generateMonth which is invoked from there).