Android - 在 AsyncTask 执行时显示进度对话框

Posted

技术标签:

【中文标题】Android - 在 AsyncTask 执行时显示进度对话框【英文标题】:Android - Show progress dialog while AsyncTask executes 【发布时间】:2019-12-31 15:13:50 【问题描述】:

我有以下课程,它调用一个发送电子邮件的 Web 服务,这可能需要 5 秒,具体取决于连接。 这个想法是在发送邮件时向用户显示一条消息,以便它处于暂停状态并且无法执行任何操作

这是我的课:

private class TareaEnviarMail extends AsyncTask<String, Void, String>
    
        ProgressDialog.Builder b;

        @Override
        protected String doInBackground(String... params)
        
            try 

                URL url = new URL("https://example.sendmail.com");
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("POST");

                InputStream in = new java.io.BufferedInputStream(conn.getInputStream());
                String response = org.apache.commons.io.IOUtils.toString(in, "UTF-8");

            
            catch(Exception ex)
            
                Log.e("Error",ex.toString());
            

            return null;

        

        @Override
        protected void onPostExecute(String result)
        
            //HERE, I WANT TO DISMISS THE DIALOG!!! LIKE b.dismiss(); ¿?
            Intent intent = new Intent(getApplicationContext(), ActividadPrincipal.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(intent);
        

        @Override
        protected void onPreExecute()
        
            b = new  ProgressDialog.Builder(ActividadNuevoTurnoSeleccionar.this);
            b.setTitle("Enviando correo. Revise su casilla.");
            b.setMessage("Por favor, espere mientras registramos el turno y le enviamos la confirmación a su casilla.");
            b.create().show();
            //ProgressDialog.show(ActividadNuevoTurnoSeleccionar.this,"Enviando correo. Revise su casilla.", "Por favor, espere mientras registramos el turno y le enviamos la confirmación a su casilla.");
        

        @Override
        protected void onProgressUpdate(Void... values) 
    

问题是当后台任务结束时,现在我不知道如何在 onpostexecute 方法中关闭对话框。由于我没有对话框,而是构建器。 你可以帮帮我吗?谢谢

【问题讨论】:

存储对ProgressDialog 的引用,而不是它的构建器,您将能够隐藏它b.create() 返回对对话框本身的引用 执行后写入 -> b.dismiss b.create() 返回一个 AlertDialog。不是 ProgressDialog 然后将其声明为AlertDialog,您可以以同样的方式将其关闭 是的,我觉得这看起来很有趣,而且我错过了一些新的 API。没有ProgressDialog.Builder本身ProgressDialog 扩展了 AlertDialog,所以这是 AlertDialogBuilder。请改用静态ProgressDialog.show() 方法之一。他们返回一个ProgressDialog,这就是你坚持的:developer.android.com/reference/android/app/… 【参考方案1】:

ProgressDialog.Builder b; 更改为对话框,例如ProgressDialog dialog;,因为您需要对话框的引用而不是它的构建器,因此您可以在 onPreExecute 上创建构建器并将它构建的对话框分配给之前声明的对话框。

@Override
        protected void onPreExecute()
        
            ProgressDialog.Builder b = new  ProgressDialog.Builder(ActividadNuevoTurnoSeleccionar.this);
            b.setTitle("Enviando correo. Revise su casilla.");
            b.setMessage("Por favor, espere mientras registramos el turno y le enviamos la confirmación a su casilla.");
            dialog = b.create();
            b.show();
            //ProgressDialog.show(ActividadNuevoTurnoSeleccionar.this,"Enviando correo. Revise su casilla.", "Por favor, espere mientras registramos el turno y le enviamos la confirmación a su casilla.");
        

然后像往常一样在 onPostExecute() 中关闭对话框;

【讨论】:

b.create() 返回一个 AlertDialog。不是 ProgressDialog。 您可以声明为 AlertDialog 或强制转换为 ProgressDialog【参考方案2】:
    private class TareaEnviarMail extends AsyncTask<String, Void, String> 
    ProgressDialog progressDialog;

    @Override
    protected String doInBackground(String... params) 
        try 

            URL url = new URL("https://example.sendmail.com");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");

            InputStream in = new java.io.BufferedInputStream(conn.getInputStream());
            String response = org.apache.commons.io.IOUtils.toString(in, "UTF-8");

         catch (Exception ex) 
            Log.e("Error", ex.toString());
        

        return null;

    

    @Override
    protected void onPostExecute(String result) 
        //HERE, I WANT TO DISMISS THE DIALOG!!! LIKE b.dismiss(); ¿?

        if(progressDialog!=null && progressDialog.isShowing())
            progressDialog.dismiss();
        Intent intent = new Intent(getApplicationContext(), ActividadPrincipal.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
    

    @Override
    protected void onPreExecute() 
        progressDialog = new ProgressDialog(ActividadNuevoTurnoSeleccionar.this);
        progressDialog.setMessage("Please wait...");
        progressDialog.setCancelable(false);
        progressDialog.show();


    

    @Override
    protected void onProgressUpdate(Void... values) 
    

【讨论】:

【参考方案3】:

创建一个进度对话框对象并用下面的代码替换 onPostExecute 和 onPreExecute

ProgressDialog dialog;

    @Override
    protected void onPostExecute(String result)
    
        dismiss.show();
        //HERE, I WANT TO DISMISS THE DIALOG!!! LIKE b.dismiss(); ¿?
        Intent intent = new Intent(getApplicationContext(), ActividadPrincipal.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
    

    @Override
    protected void onPreExecute()
    
       dialog= new  ProgressDialog.Builder(ActividadNuevoTurnoSeleccionar.this)
        .setTitle("Enviando correo. Revise su casilla.")
        .setMessage("Por favor, espere mientras registramos el turno y le enviamos la confirmación a su casilla.")
        .create();
        dialog.show();
        //ProgressDialog.show(ActividadNuevoTurnoSeleccionar.this,"Enviando correo. Revise su casilla.", "Por favor, espere mientras registramos el turno y le enviamos la confirmación a su casilla.");
    

【讨论】:

【参考方案4】:

另一种解决方案是不使用构建器。

ProgressDialog b;

在预执行时

@Override
    protected void onPreExecute()
    
        b = new  ProgressDialog(ActividadNuevoTurnoSeleccionar.this);
        b.setTitle("Enviando correo. Revise su casilla.");
        b.setMessage("Por favor, espere mientras registramos el turno y le enviamos la confirmación a su casilla.");
        b.create();
        b.show();
    

然后,在 postExecute 中照常将其关闭。

【讨论】:

以上是关于Android - 在 AsyncTask 执行时显示进度对话框的主要内容,如果未能解决你的问题,请参考以下文章

Android - 在 AsyncTask 执行时显示进度对话框

Android AsyncTask分析

Android - 仅在 AsyncTask 未完成时单击按钮时显示进度对话框

Android 对线程封装了:AsyncTask, HandlerThread和线程池。 有知道这三个如何选择吗?

Android攻城狮AsyncTask

android中asynctask和thread的区别