我有一个应用程序,上面有一个大红色投票按钮。现在,我总是要求他们有一个公共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);
}
答案 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
调用它