我有一个 AsynTask,当 doInBackground 方法调用另一个试图显示警报对话框的类时,它会使整个应用程序崩溃。
下面是我的AsynTask,
private class ReserveAppointmentTask extends AsyncTask<Void, Void, Void>{
@Override
protected void onPreExecute() {
showDialog(RESERVING_PROGRESS_DIALOG);
}
@Override
protected Void doInBackground(Void... params) {
WebServiceResponse.appointmentReservation(AppointmentConfirmationActivity.this, appointmentObj);
return null;
}
@Override
protected void onPostExecute(Void response) {
removeDialog(RESERVING_PROGRESS_DIALOG);
}
}
WebserviceResponse.appointmentReservation 方法包含以下代码,我知道它进入下面所述的 if 条件的事实,
public static void appointmentReservation(AppointmentConfirmationActivity activity, Appointment appointmentObj){
SetAppointmentResponse setAppointmentResponse = SetAppointmentResponse.extractJSONResponse(response);
if(setAppointmentResponse.checkResponse()== RESPONSES.SUCCESSFULL){
Dialogs.initAppointmentReservedDialog(activity);
}
}
Dialogs.initAppointmentReservedDialog 包含以下内容,
public static void initAppointmentReservedDialog(final Activity activity){
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage(activity.getString(R.string.appointment_reserved_dialog)).setCancelable(false).setPositiveButton(activity.getString(R.string.ok_button_dialog), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent nextScreen = new Intent(activity, MainOptionsActivity.class);
activity.startActivity(nextScreen);
}
});
AlertDialog alert = builder.create();
alert.show();
}
我在日志中收到以下致命异常,
07-18 10:59:34.882: E/AndroidRuntime(4885): FATAL EXCEPTION: AsyncTask #2
07-18 10:59:34.882: E/AndroidRuntime(4885): java.lang.RuntimeException: An error occured while executing doInBackground()
07-18 10:59:34.882: E/AndroidRuntime(4885): at android.os.AsyncTask$3.done(AsyncTask.java:278)
07-18 10:59:34.882: E/AndroidRuntime(4885): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
07-18 10:59:34.882: E/AndroidRuntime(4885): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
07-18 10:59:34.882: E/AndroidRuntime(4885): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
07-18 10:59:34.882: E/AndroidRuntime(4885): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
07-18 10:59:34.882: E/AndroidRuntime(4885): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
07-18 10:59:34.882: E/AndroidRuntime(4885): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
07-18 10:59:34.882: E/AndroidRuntime(4885): at java.lang.Thread.run(Thread.java:856)
07-18 10:59:34.882: E/AndroidRuntime(4885): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
07-18 10:59:34.882: E/AndroidRuntime(4885): at android.os.Handler.<init>(Handler.java:121)
07-18 10:59:34.882: E/AndroidRuntime(4885): at android.app.Dialog.<init>(Dialog.java:107)
07-18 10:59:34.882: E/AndroidRuntime(4885): at android.app.AlertDialog.<init>(AlertDialog.java:114)
07-18 10:59:34.882: E/AndroidRuntime(4885): at android.app.AlertDialog$Builder.create(AlertDialog.java:913)
07-18 10:59:34.882: E/AndroidRuntime(4885): at org.digitalhealthagency.elaj.util.Dialogs.initAppointmentReservedDialog(Dialogs.java:277)
07-18 10:59:34.882: E/AndroidRuntime(4885): at org.digitalhealthagency.elaj.webservice.WebServiceResponse.appointmentReservation(WebServiceResponse.java:288)
07-18 10:59:34.882: E/AndroidRuntime(4885): at org.digitalhealthagency.elaj.gui.AppointmentConfirmationActivity$ReserveAppointmentTask.doInBackground(AppointmentConfirmationActivity.java:182)
07-18 10:59:34.882: E/AndroidRuntime(4885): at org.digitalhealthagency.elaj.gui.AppointmentConfirmationActivity$ReserveAppointmentTask.doInBackground(AppointmentConfirmationActivity.java:1)
07-18 10:59:34.882: E/AndroidRuntime(4885): at android.os.AsyncTask$2.call(AsyncTask.java:264)
07-18 10:59:34.882: E/AndroidRuntime(4885): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
07-18 10:59:34.882: E/AndroidRuntime(4885): ... 4 more
如有任何帮助,我将不胜感激。
最佳答案
原因如@PareshMayani 所说:您无法在 doInBackground()
内部操作时更新 UI。是的,你可以,但为此你必须包含 runOnUiThread()
或使用 onPostExecute()
我会建议在流程结束后更新 UI 进行此类更改
private class ReserveAppointmentTask extends AsyncTask<Void, Void, Integer>{
@Override
protected void onPreExecute() {
showDialog(RESERVING_PROGRESS_DIALOG);
}
@Override
protected Integer doInBackground(Void... params) {
return WebServiceResponse.appointmentReservation(AppointmentConfirmationActivity.this, appointmentObj);
}
@Override
protected void onPostExecute(Integer response) {
removeDialog(RESERVING_PROGRESS_DIALOG);
if(response == RESPONSES.SUCCESSFULL){
Dialogs.initAppointmentReservedDialog(activity);
}
}
}
现在像这样改变你的方法 appointmentReservation()
public static int appointmentReservation(AppointmentConfirmationActivity activity, Appointment appointmentObj){
SetAppointmentResponse setAppointmentResponse = SetAppointmentResponse.extractJSONResponse(response);
return setAppointmentResponse.checkResponse();
}
关于Android:显示警报对话框时 AsynTask 使应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11538513/