如何显示错误对话框并在加载对话框中退出

时间:2012-04-17 20:47:24

标签: android dialog android-asynctask

我的Android应用程序首先加载所有必要的数据,同时显示加载对话框:

// Load data in background, while updating the loading dialog.
(new AsyncTask<Void, String, Void>() {
    @Override
    protected Void doInBackground(Void... params) {
        publishProgress(getString(R.string.loading_a));
        if!(loadA())
            showErrorDialogAndQuit();
        publishProgress(getString(R.string.loading_b));
        if(!loadB())
            showErrorDialogAndQuit();
        publishProgress(getString(R.string.loading_c));
        if(!loadC())
            showErrorDialogAndQuit();
        return null;
    }

    protected void onProgressUpdate(String... progress) {
        dialog.setMessage(progress[0]);
    }

    protected void onPostExecute(Void result) {
        // Update the UI.
        updateUI();
        dialog.dismiss();
    }
}).execute();

方法loadA()loadB()loadC()可能会失败,返回false。此时,我希望显示一条错误消息,并在方法showErrorDialogAndQuit()中退出该应用程序。

我尝试按如下方式创建它,但是在应用程序退出后似乎总是抛出错误,这与加载对话框不再有窗口有关。

public void showErrorDialogAndQuit() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            AlertDialog aDialog = new AlertDialog.Builder(MyActivity.this).setMessage("Fatal error.").setTitle("Error")
                    .setNeutralButton("Close", new AlertDialog.OnClickListener() {
                        public void onClick(final DialogInterface dialog, final int which) {
                            // Exit the application.
                            finish();
                        }
                    }).create();
            aDialog.setOnKeyListener(new OnKeyListener() {
                @Override
                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                    // Disables the back button.
                    return true;
                }

            });
            aDialog.show();
        }
    });
}

实现这一目标的最佳方法是什么?

2 个答案:

答案 0 :(得分:0)

如果只有在成功加载A后才能执行loadB,我建议您更改代码的逻辑。您可以使用具有3种状态的最终状态机方法,其中stateA在stateA完成后被触发。

使用处理程序也可以很好地更新UI。逻辑可能如下所示:

  1. 在主体中启动Thread loadingA
  2. 在threadA中 如果成功将msg A_success发送到主体 否则将msg A_failed发送到主体 threadA到此结束
  3. 主体通过处理程序接收消息并继续 如果收到A_success - &gt;启动线程loadingB 否则结束(或任何你想要的)
  4. 启动threadA如下所示:

      new Thread(new Runnable() {
        public void run() {
            loadingA();
        }
        }).start();
    

    在loadingA中,你将msg发送回主体:

     public void loadingA() {
        ...do your loading...
    
        then to inform the main body...
    
        Message msg = mHandlerToReceiveTheResultFromLoadingThread
                .obtainMessage(MESSAGE_UPDATE_RESULT_OF_LOADING_A);
            Bundle bundle = new Bundle();
            bundle.putBoolean(RESULT_OK_INFO, true or false);
            msg.setData(bundle);
            mHandlerToReceiveTheResultFromLoadingThread
                .sendMessage(msg);
    
            }
    

    在主体中mHandlerToReceiveTheResultFromLoadingThread看起来像:

    public final Handler mHandlerToReceiveTheResultFromLoadingThread = new Handler() {
        @Override
        public void handleMessage(Message msg) {
    
            if (DEBUG)
            Log.i(this.getClass().getSimpleName(),
                "-> "
                    + Thread.currentThread().getStackTrace()[2]
                        .getMethodName() );
            switch (msg.what) {
            case MESSAGE_UPDATE_RESULT_OF_LOADING_A: {
            boolean result_ok = msg.getData().getBoolean(RESULT_OK_INFO);
    
            if (result_ok)
                ...continue with loadingB;
                else
                   show your message that it failed and exit;
            }
            break;
    
            }
    
        }
    

    希望这会有所帮助......

    编辑:在活动的逻辑结束时调用完成:

            this.myBtn.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {   
                    String msg = "Hello, I have finished and started another activity";
                    doOtherActivit(msg); 
                    finish();
                }
            });
        }
    
    public void doOtherActivity(String msg) {
            Intent i;
            i = new Intent(this, OtherActivity.class);
            i.putExtra("Task", msg);        
            startActivity(i);
        }
    

答案 1 :(得分:0)

原来我需要做的就是在调用finish()之前自然关闭进度对话框:

if(!loadA()) {
    showErrorDialogAndQuit();
    return null;
}

这可以通过创建错误对话框来实现,该对话框在另一个线程中运行,然后将null返回到AsyncTask,使其运行onPostExecute()并关闭进度对话框。然后,当按下错误对话框中的关闭按钮并调用finish()时,一切都可以正常关闭。

这种方法的唯一缺点是,如果在onPostExecute()中发生了比更新UI更重要的事情。在这种情况下,您可以修改参数类型并对其进行测试以查看要执行的操作。