Android:显示警报对话框时 AsynTask 使应用程序崩溃

标签 android android-asynctask android-alertdialog

我有一个 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/

相关文章:

java - 添加 AsyncTask - Android

android - 有没有办法防止 AlertDialog 因输入无效而关闭?

android - 基本的 Android 许可查询

android - 在 Android 上启动日历应用程序的通用 Intent ?

java - 为什么Java中有些方法不需要创建实例就可以使用?

android - 如何在膨胀的布局中膨胀具有相同 id 的布局的多个实例

java - Android:AsyncTask doInBackground 中的 if 语句

php - 如何使用 HttpURLConnection 在 php 中发送 json 以读取 'php://input'?

android - 在 Android 上将值从 Dialog 传回 Activity 的可靠方法?

android - 如何获取单选警报对话框的选定项目?