当doInBackground方法调用另一个试图显示alertdialog的类时,我有一个AsynTask会崩溃整个应用程序。
以下是我的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
我将不胜感激。
答案 0 :(得分:3)
原因如@PareshMayani所说:在doInBackground()
内部进行操作时无法更新UI。是的,您可以,但为此您必须包含runOnUiThread()
或使用onPostExecute()
我建议在进程
之后更新UIprivate 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();
}
答案 1 :(得分:1)
将修改UI的部分移动到onPostExecute
方法..
@Override
protected SetAppointmentResponse doInBackground(Void... params) {
return WebServiceResponse.appointmentReservation(AppointmentConfirmationActivity.this, appointmentObj);
}
@Override
protected void onPostExecute(SetAppointmentResponse response) {
if(response.checkResponse()== RESPONSES.SUCCESSFULL){
Dialogs.initAppointmentReservedDialog(activity);
}
removeDialog(RESERVING_PROGRESS_DIALOG);
}
appointmentReservation
需要修改为:
public static SetAppointmentResponse appointmentReservation(AppointmentConfirmationActivity activity, Appointment appointmentObj){
return SetAppointmentResponse.extractJSONResponse(response);
}
答案 2 :(得分:1)
您可以使用Handler对象执行您想要的操作。
在您的WebServiceResponse类中添加此静态方法(初始化一个新的Handler)
public static Handler initHandler() {
return new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 0) {
Dialogs.initAppointmentReservedDialog(activity);
}
}
};
}
在onPreExecute方法的ReserveAppointmentTask类中调用此方法。 保持对此Handler的引用并将其传递给appointmentReservation方法。 然后修改此方法的代码,如下所示:
public static void appointmentReservation(AppointmentConfirmationActivity activity, Appointment appointmentObj, Handler handler){
SetAppointmentResponse setAppointmentResponse = SetAppointmentResponse.extractJSONResponse(response);
if(setAppointmentResponse.checkResponse()== RESPONSES.SUCCESSFULL){
handler.sendEmptyMessage(0);
}
}
要更好地了解Handler,请查看这个精彩的教程:http://www.vogella.com/articles/AndroidPerformance/article.html。
我希望这会对你有所帮助。