尝试弹出警报框以响应AsyncTask

时间:2016-02-07 19:52:21

标签: java android android-asynctask android-alertdialog

我有一个应用程序,上面有一个大红色投票按钮。现在,我总是要求他们有一个公共IP地址才能启用投票按钮。

我了解到我需要通过AsyncTask获取互联网内容,因此我创建了一个名为DetermineIP的新类扩展。这个过程有效,我能够获得IP,因为我有一个我建的网页,只提供IP。

我现在正在处理他们没有连接时的处理。所以,我建立了一个警告框,它上面有一个重试按钮。目标是允许用户修复他们的连接问题,然后点击重试,直到他们获得他们的IP。

我认为我似乎无法添加点击处理程序,因为它是从AsyncTask调用的。我得到:引起:java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序

我完全承认自己是一个菜鸟,我真的只是想找到一种方法来实现这一目标。

public void fetchIP()
{
    // UPDATE LABELS
    Resources res = getResources();

    TextView textStatus = (TextView) findViewById(R.id.statusMessage);
    textStatus.setText(res.getString(R.string.status_determining_ip_address));

    enableVoteButton(false);

    String stringURL = res.getString(R.string.ip_url);
    URL urlIP = null;
    try {
        urlIP = new URL(stringURL);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }

    // start AsyncTask to fetch IP in the background
    getIP = new DetermineIP();
    getIP.setParent(this);
    getIP.execute(urlIP);
    m_working = true;

    // show a dialog box with message that we're determining the IP
    status_dialog = new Dialog(MainActivity.this);
    status_dialog.setCancelable(false);
    status_dialog.setContentView(R.layout.activity_ip);
    TextView textDialogStatus = (TextView) status_dialog.findViewById(R.id.textView);
    textDialogStatus.setText(R.string.status_determining_ip_address);
    status_dialog.show();
}

// If we were able to determine the IP address by fetching from a
// public web server then everything's good. Enable everything, and
// move along from there. Called from DetermineIP.onPostExecute.
public void setIP(String theIP)
{
    m_ip = theIP;

    TextView textStatus = (TextView) findViewById(R.id.statusMessage);
    textStatus.setText(m_ip);
    enableVoteButton(true);
    m_working = false;
    status_dialog.dismiss();
}

// If we were unable to determine an IP address, for whatever reason,
// show a retry alert box, when they hit retry, then start the process
// over again, maybe the user needs to solve a connectivity issue before
// retrying. Called from DetermineIP.onPostExecute.
public void setNoIP()
{
    Resources res = getResources();

    TextView textStatus = (TextView) findViewById(R.id.statusMessage);
    textStatus.setText(res.getString(R.string.status_unable_to_determine_ip_address));
    enableVoteButton(false);
    m_working = false;

    status_dialog.dismiss();
    RetryDialog();
}

// this is the dialog that informs the user that no IP was determined.
// clicking Retry will start the process of finding the IP again.
private void RetryDialog()
{
    Resources res = getResources();

    AlertDialog.Builder builder1 = new AlertDialog.Builder(MainActivity.this);
    builder1.setMessage(res.getString(R.string.status_unable_to_determine_ip_address));
    builder1.setCancelable(false);

    builder1.setPositiveButton(
            "Retry",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
                    fetchIP();
                }
            });

    AlertDialog alert11 = builder1.create();
    alert11.show();

}

在DetermineIP.onPostExecute

protected void onPostExecute(String result) {
    if(result.isEmpty()) ((MainActivity) m_parent).setNoIP();
    else ((MainActivity) m_parent).setIP(result);
}

2 个答案:

答案 0 :(得分:1)

AsyncTask对UI的任何更新都可以通过以下方式完成 -

protected void onPostExecute(Object result) {

            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    //UI related code
                }
            });
        }

答案 1 :(得分:0)

您强烈建议您执行主UI线程的UI更新的错误。如果要更新视图,则应在UI线程上执行此操作。 AsyncTask有一个 回调,您可以根据需要更新UI:

 @Override 
        protected void onPostExecute(Object result) {
        } 

并且有一个onPreExecute

Android的黄金法则 - > 在另一个线程上做大量工作(比如做AsyncTask的doInBackground)并在主线程上更新UI

所以任何UI相关的东西都只是从主线程调用它而不是从asyncTask doInBackground

调用它