【问题标题】:Android, how to display a dialog from error of a try catch?Android,如何从尝试捕获错误中显示对话框?
【发布时间】:2012-06-08 18:23:48
【问题描述】:

在我的应用程序中,我连接到一个网站以从 AsyncTask 开始收集一些信息,使用 try catch,从这里我可以在我的目录日志中显示连接时的错误(如果有),但我一直在尝试没有运气显示一个对话框,显示连接失败以及重新连接或退出的选项,请检查我的代码并告诉我我做错了什么或如何完成此操作的想法

 //this is our download file asynctask
class DownloadFileAsync extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        showDialog(DIALOG_DOWNLOAD_PROGRESS);
    }

    @Override
    protected String doInBackground(String... aurl) {

        try {
        String result = "";
                    try {
                        HttpClient httpclient = new DefaultHttpClient();
                        HttpPost httppost = new HttpPost("http://mywebsiteaddress");
                        // httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                        HttpResponse response = httpclient.execute(httppost);
                        HttpEntity entity = response.getEntity();
                        InputStream webs = entity.getContent();
                        // convert response to string
                        try {
                            BufferedReader reader = new BufferedReader(
                                    new InputStreamReader(webs, "iso-8859-1"), 8);
                            StringBuilder sb = new StringBuilder();
                            String line = null;
                            while ((line = reader.readLine()) != null) {
                                sb.append(line + "\n");
                            }
                            webs.close();

                            result = sb.toString();
                        } catch (Exception e) {
                            Log.e("log_tag", "Error converting result " + e.toString());
                        }
                    } catch (Exception e) {
                        Log.e("log_tag", "Error in http connection " + e.toString());
                    }

                    // parse json data
                    try {
                        JSONArray jArray = new JSONArray(result);
                        for (int i = 0; i < jArray.length(); i++) {
                            JSONObject json_data = jArray.getJSONObject(i);
                            webResult resultRow = new webResult();
                            //infotodownload
                            arrayOfWebData.add(resultRow);

                        }
                    } catch (JSONException e) {
                        Log.e("log_tag", "Error parsing data " + e.toString());
                    }
    } catch (Exception e) {
        // this is the line of code that sends a real error message to the
        // log
        Log.e("ERROR", "ERROR IN CODE: " + e.toString());
        // this is the line that prints out the location in
        // the code where the error occurred.
        e.printStackTrace();
    }
        return null;
    }

    protected void onProgressUpdate(String... progress) {
         Log.d(LOG_TAG,progress[0]);
         mProgressDialog.setProgress(Integer.parseInt(progress[0]));
    }

    @Override
    protected void onPostExecute(String unused) {
        //dismiss the dialog after the file was downloaded
        dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
    }

}

//our progress bar settings
@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
        case DIALOG_DOWNLOAD_PROGRESS: //we set this to 0
            mProgressDialog = new ProgressDialog(this);
            mProgressDialog.setTitle("Conectando al Servidor");
            mProgressDialog.setMessage("Cargando informacion...");
            mProgressDialog.setIndeterminate(false);
            mProgressDialog.setMax(100);
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            mProgressDialog.setCancelable(true);
            mProgressDialog.show();
            return mProgressDialog;
        default:
            return null;
    }
}

编辑: 然后我尝试按照 Arun 的建议添加下一个代码

 catch (Exception e) {
        // this is the line of code that sends a real error message to the
        // log
        Log.e("ERROR", "ERROR IN CODE: " + e.toString());
        // this is the line that prints out the location in
        // the code where the error occurred.
        e.printStackTrace();
        return "ERROR_IN_CODE";
    }
       return null;       // if I place here return "ERROR_IN_CODE" it calls the dialog but it gets always called so I don't need it here
    }

    @Override
    protected void onPostExecute(String unused) {
        //dismiss the dialog after the file was downloaded
        dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
        if(unused.equals("ERROR_IN_CODE")){                 //I get a system crash here!
            errornote();
        }
    }

}

public void errornote() {
    AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);
    alt_bld.setMessage("No se a podido descargar la informacion de los medios, deseas reintentarlo, o salir?").setCancelable(false)
            .setPositiveButton("Conectar de Nuevo", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    new DownloadFileAsync().execute();
                }
            })
            .setNegativeButton("Salir", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    // Action for 'NO' Button
                    finish();
                }
            });
    AlertDialog alert = alt_bld.create();
    // Title for AlertDialog
    alert.setTitle("Error en la Conexion!");
    // Icon for AlertDialog
    alert.setIcon(android.R.drawable.ic_dialog_alert);
    alert.show();
}

但也不工作,我的应用程序在 onPostExecute 的 if 语句行中崩溃。我仍然需要帮助。

【问题讨论】:

  • doInBackground() 的 Catch 块中无法显示对话框,因为此函数在非 UI 线程中运行
  • 看看答案here有没有帮助。
  • @yorkw,不显示对话框。
  • 根据你上次编辑,似乎代码执行没有遇到catch块,确保你的catch块被正确触发,换句话说,确保try块中的代码失败并抛出实际异常。
  • @ yorkw,我所做的测试只是断开我的互联网与计算机的连接,当模拟器尝试连接以下载它无法下载的信息时,它会得到一个连接错误。你是这个意思吗?

标签: java android eclipse try-catch


【解决方案1】:

由于您从 protected String doInBackground(String... aurl) 返回一个字符串对象,因此从 catch 块返回一些自定义错误字符串并在 protected void onPostExecute(String unused) 中访问它。检查返回的字符串对象是否是自定义错误字符串并在protected void onPostExecute(String unused) 中显示对话框,但仅在关闭progressDialog 之后,即在此行之后dismissDialog(DIALOG_DOWNLOAD_PROGRESS); 显示错误对话框。

编辑

当控件进入 Catch 块时,返回一些简单的字符串,例如您使用的“ERROR_IN_CODE”。

catch (Exception e) {
    // this is the line of code that sends a real error message to the
    // log
    Log.e("ERROR", "ERROR IN CODE: " + e.toString());
    // this is the line that prints out the location in
    // the code where the error occurred.
    e.printStackTrace();

    return "ERROR_IN_CODE";
}

onPostExecute(String unused) 中检查以下内容

protected void onPostExecute(String unused) {
    //dismiss the dialog after the file was downloaded
    dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
    if(unused != null && unused.equals("ERROR_IN_CODE")){
        showDialog(SOME_DIALOG_TO_SHOW_ERROR);
    }
}

【讨论】:

  • @ Arun 感谢您提供所有信息,我喜欢您对我的问题的处理方法,但我对这一切有点陌生,您能否给我一个关于如何实现自定义错误字符串的示例我的代码?谢谢
  • @ Arun,我已经尝试过了,但它一直在使应用程序崩溃,在 logcat 中,我在第 410 行给出了一个错误,其中我有 if(unused.equals.....
  • @zvzej 为什么在 Catch 块之后返回空值?我想如果您没有遇到任何错误,您应该返回结果字符串。无论如何,我已经编辑了 onPostExecute(String used) 并添加了空检查,这应该可以解决您的问题。
  • @Arun,搞定了!非常感谢!,在返回 null 中,我只能说我从在线教程中获得了这部分代码,这就是它的方式,它在我的情况下有效。我只需要添加返回“ERROR_IN_CODE”;到 Asynctask 中的所有 catch 情况,以便在任何错误情况下都可以调用它。再次感谢您。
【解决方案2】:

尝试调用您的活动 runOnUiThread() 方法

activity.runOnUiThread(new Runnable() {
        public void run() {
            //your alert dialog builder here
    });

【讨论】:

  • @ian,我应该在哪里以及如何实现这个?
  • @yorkw,你能解释一下如何或在哪里使用它吗?
  • @zvzej,假设您将 AsyncTask 实现为 Activity 的内部类,请查看示例代码 here
【解决方案3】:

您没有使用 builder 创建 AlertDialog 删除builder.show()这一行并添加

AlertDialog alert = builder.create();
alert.show();

我还建议通过 progressUpdate()preExecute() 和 asyc 任务的 'postExecute()' 进行 UI 更新。

实施

@ReactMethod
    public void showCustomAlert(String msg){

        final String message = msg;

        this.reactContext.runOnUiQueueThread(new Runnable() {
            @Override
            public void run() {
                AlertDialog.Builder myDialogBox = new AlertDialog.Builder(reactContext.getCurrentActivity());
                myDialogBox.setTitle(Html.fromHtml("<font color='#0037FF'>Konnect</font>"));
                myDialogBox.setMessage(message);
                myDialogBox.setCancelable(true);
                myDialogBox.setPositiveButton("Ok", new DialogInterface.OnClickListener(){

                    public void onClick(DialogInterface dialog, int whichButton) {
                            dialog.dismiss();
                    }

                });
                AlertDialog alertDialog = myDialogBox.create();
                if (Build.VERSION.SDK_INT <= 23) {
                    alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
                }else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
                }else {
                    alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE);
                }

                alertDialog.show();

                WindowManager.LayoutParams wmlp = alertDialog.getWindow().getAttributes();
                wmlp.gravity = Gravity.TOP | Gravity.LEFT;
                wmlp.x = 25;   //x position
                wmlp.y = 450;   //y position
                wmlp.height = 380;
                alertDialog.show();
                alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.WHITE));
            }
        });
    }

【讨论】:

  • AlertDialog.Builder.show() 与您在此处建议的操作完全相同。它只是一个较短的变体。见the source code
  • 如何在 doInBackground() 中显示一个对话框,因为它在非 UI 线程上运行?
  • 对不起@Orlymee 当你编辑你的帖子时我还在写评论。我想删除我的反对票,但它显示了一个对话框,上面写着“您上次在 8 分钟前对此答案投票,除非编辑此答案,否则您的投票现在已锁定”
  • @ Orlymee,您能否使用我的代码给我一个示例,说明如何实现您的想法。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多