执行两个异步任务并更新AsyncTask消息

时间:2014-06-17 22:33:37

标签: android android-asynctask progressdialog ui-thread

我有一段代码连接到服务器然后登录。当执行这两项任务(连接到服务器登录)时,进展对话框出现。

final ProgressDialog pd = new ProgressDialog(getActivity());
pd.setIndeterminate(true);
pd.setCancelable(false);

// While connecting to the server, the dialog should say the following:
pd.setTitle("Connecting...");
pd.setMessage("Connecting to " + hostname + "...");

pd.show();

new AsyncTask<Void, Void, Void>() {

    @Override
    protected Void doInBackground(Void... params) {
        try {

            // First task is executed. Progress dialog should say "Connecting..."
            executeTask1();

            // When the first task (connecting to server) is ready, I want the title
            // and the message of the progress dialog to be changed into this:
            pd.setTitle("Logging in"); //// MARKED LINE, see below. ////
            pd.setMessage("Trying to log in to server...");

            // Second task is executed.
            executeTask2();

            // Shows a screen and dismisses the ProgressDialog.
            showScreen(ScreenConstant.LIST_RESIDENTS);
            pd.dismiss();
        }
        catch (Exception exc) { }
    }
}

但我遇到了两个问题:

  1. 执行MARKED LINE(见上文)时会引发RuntimeException:“只有创建视图层次结构的原始线程才能触及其视图”
  2. 登录任务从服务器获取响应,但此响应是异步的。
  3. 在执行连接尝试时,我希望ProgressDialog显示“正在连接...”文本。连接成功后,我希望在执行登录尝试时将进度对话框的文本更改为“登录...”。

    现在我应该如何实现这个目标?

    修改

    请注意,executeTask2()会触发在不同主题中运行的任务;它向服务器发送一个登录请求,因此我需要等到该线程在准备就绪时发出信号。

2 个答案:

答案 0 :(得分:0)

任何触及UI的代码都应该在主线程上完成,因此您需要使用onProgressUpdate()publishProgress()来实现此目的。

例如:

public void onProgressUpdate(Void... progress){
    super.onProgressUpdate(progress);
    pd.setTitle("Logging in");
    pd.setMessage("Trying to log in to server..."):
}

并在您的doInBackground()方法中:

executeTask1();
//task one finished, update UI
publishProgress();

除此之外,您应该忽略ProgressDialog中的onPostExecute(),因为这也会在主线程上执行

答案 1 :(得分:0)

您需要在主线程中运行进度对话框,只有创建视图的线程才能更新或调用它,从而为您提供异常。

<强>样品:

    @Override
    protected Void doInBackground(Void... params) {
        try {

            // First task is executed. Progress dialog should say "Connecting..."
            executeTask1();

            // When the first task (connecting to server) is ready, I want the title
            // and the message of the progress dialog to be changed into this:
            getActivity().runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    pd.setTitle("Logging in"); //// MARKED LINE, see below. ////
                    pd.setMessage("Trying to log in to server...");
                }
            });


            // Second task is executed.
            executeTask2();

            // Shows a screen and dismisses the ProgressDialog.
            showScreen(ScreenConstant.LIST_RESIDENTS);

            getActivity().runOnUiThread(new Runnable() {

                @Override
                public void run() {
                 pd.dismiss();  


                }
            });

        }
        catch (Exception exc) { }
    }

注意:

在主线程中运行的post execute Asynctask方法中删除对话框是明智的。