“忙”进度对话框导致奇怪的代码处理
让我为您总结一下情况:
- 我有一个按钮(btnChooseEp),当您按下它时,会出现一个 AlertDialog。
- 当在 AlertDialog 中选择某些内容时,必须评估三个 if 语句。
- 当它们被评估时,会出现一个 ProgressDialog。它表明该应用程序“忙”。
- 在评估这些语句之后,ProgressDialog 必须消失。
我的问题在代码下面描述。
整个代码块如下所示:
ProgressDialog getTracklistProgressDialog = null;
...
Button btnChooseEp = (Button)findViewById(R.id.btnChooseEp);
btnChooseEp.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
final AlertDialog.Builder builder = new AlertDialog.Builder(GA.this);
builder.setTitle(getText(R.string.chooseEpisode));
builder.setItems(episodes, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, final int pos)
{
getTracklistProgressDialog = ProgressDialog.show(GA.this, "Please wait...",
"Retrieving tracklist...", true);
new Thread()
{
public void run()
{
try
{
String str1, epURL;
if(pos < 9)
{
str1 = getResources().getString(R.string.epNo1);
epURL = String.format(str1, pos+1);
setTracklist(epURL, tracklist);
}
else if(pos < 100)
{
str1 = getResources().getString(R.string.epNo2);
epURL = String.format(str1, pos+1);
setTracklist(epURL, tracklist);
}
else if(pos >= 100)
{
str1 = getResources().getString(R.string.epNo3);
epURL = String.format(str1, pos+1);
setTracklist(epURL, tracklist);
}
}
catch(Exception e)
{}
// Remove progress dialog
getTracklistProgressDialog.dismiss();
}
}.start();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
});
不确定是否需要,但这里是函数 setTracklist 的代码:
public void setTracklist(String string, TextView tv)
{
try
{
tv.setText(getStringFromUrl(string));
}
catch(Exception e)
{
e.printStackTrace();
}
}
函数 getStringFromUrl 的代码可以在这里看到: http://pastebin.com/xYt3FwaS
现在,问题是: 当我没有实现 ProgressDialog 的时候(我从这里得到的,顺便说一句: http: //www.anddev.org/tinytut_-_displaying_a_simple_progressdialog-t250.html),它工作得很好 - setTracklist 函数从互联网上的文本文件中检索字符串,并将文本设置为 TextView。现在,当我添加 ProgressDialog 代码并将原始代码放入 try 语句中时,只有文本文件的一小部分添加到 TextView - 大约 22-24 个字符,而不是更多。 “繁忙”的 ProgressDialog 显示得很好。之前它运行得很好;它能够将超过 1300 个字符加载到 TextView 中。 我不知道这是否与线程有关 - 我用谷歌搜索了很多,但没有找到答案。
那么,如何让它加载所有数据而不是仅加载一小部分数据呢?
(顺便说一句,我希望能够在所有 if 语句下方设置“setTracklist(epURL, tracklist);”行,但随后它说它无法解析“epURL”。编写相同的代码似乎很愚蠢行 3 次!)
用当前代码更新 25/1:
final Handler uiHandler = new Handler();
final Button btnChooseEp = (Button)findViewById(R.id.btnChooseEp);
btnChooseEp.setEnabled(false);
btnChooseEp.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
builder.setTitle(getText(R.string.chooseEpisode));
builder.setItems(episodes2, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, final int pos)
{
replay.setVisibility(View.VISIBLE);
replayWeb.setVisibility(View.VISIBLE);
getTracklistProgressDialog = ProgressDialog.show(GA.this, "Please wait...",
"Retrieving tracklist...", true);
new Thread()
{
public void run()
{
try
{
String str1, epURL;
if(pos < 9)
{
str1 = getResources().getString(R.string.gaEpNo1);
epURL = String.format(str1, pos+1);
setTracklist2(epURL, tracklist);
}
else if(pos < 100)
{
str1 = getResources().getString(R.string.gaEpNo2);
epURL = String.format(str1, pos+1);
setTracklist2(epURL, tracklist);
}
else if(pos >= 100)
{
str1 = getResources().getString(R.string.gaEpNo3);
epURL = String.format(str1, pos+1);
setTracklist2(epURL, tracklist);
}
}
catch(Exception e)
{}
// Remove progress dialog
uiHandler.post(new Runnable()
{
public void run()
{
getTracklistProgressDialog.dismiss();
}
}
);
}
}.start();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
});
public void setTracklist2(final String string, final TextView tv)
{
try
{
uiHandler.post(
new Runnable()
{
public void run()
{
try
{
tv.setText(getStringFromUrl(string));
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
}
});
}
catch(Exception e)
{
e.printStackTrace();
}
}
注意:“replay”和“replayWeb”只是两个 TextView。当按下另一个按钮时,“btnChooseEp”被启用。
Let me sum up the situation for you:
- I have a button (btnChooseEp), and when you press it an AlertDialog appears.
- When something is picked in the AlertDialog, three if statements must be evaluated.
- While they are being evaluated, a ProgressDialog appears. It indicates that the app is "busy".
- After the evaluation of these statements, the ProgressDialog must disappear.
My problem is described beneath the code.
The entire code block is shown here:
ProgressDialog getTracklistProgressDialog = null;
...
Button btnChooseEp = (Button)findViewById(R.id.btnChooseEp);
btnChooseEp.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
final AlertDialog.Builder builder = new AlertDialog.Builder(GA.this);
builder.setTitle(getText(R.string.chooseEpisode));
builder.setItems(episodes, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, final int pos)
{
getTracklistProgressDialog = ProgressDialog.show(GA.this, "Please wait...",
"Retrieving tracklist...", true);
new Thread()
{
public void run()
{
try
{
String str1, epURL;
if(pos < 9)
{
str1 = getResources().getString(R.string.epNo1);
epURL = String.format(str1, pos+1);
setTracklist(epURL, tracklist);
}
else if(pos < 100)
{
str1 = getResources().getString(R.string.epNo2);
epURL = String.format(str1, pos+1);
setTracklist(epURL, tracklist);
}
else if(pos >= 100)
{
str1 = getResources().getString(R.string.epNo3);
epURL = String.format(str1, pos+1);
setTracklist(epURL, tracklist);
}
}
catch(Exception e)
{}
// Remove progress dialog
getTracklistProgressDialog.dismiss();
}
}.start();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
});
Not sure if needed, but here is the code for the function setTracklist:
public void setTracklist(String string, TextView tv)
{
try
{
tv.setText(getStringFromUrl(string));
}
catch(Exception e)
{
e.printStackTrace();
}
}
And the code for the function getStringFromUrl can be seen here: http://pastebin.com/xYt3FwaS
Now, the problem:
Back when I didn't implement the ProgressDialog thing (which I have from here, btw: http://www.anddev.org/tinytut_-_displaying_a_simple_progressdialog-t250.html), it worked fine - the setTracklist function retrieves a string from a text file on the internet, and sets the text to a TextView. Now, when I have added the ProgressDialog code, and put the original code into the try statement, only a very little part of the text file is added to the TextView - approximately 22-24 characters, not more. The "busy" ProgressDialog shows up just fine. It worked perfectly before; it was more than capable of loading more than 1300 characters into the TextView.
I don't know if it has anything to do with the thread - I have Googled a lot and found no answer.
So, how do I get it to load in all data instead of just a small part?
(By the way, I would love to be able to set the line "setTracklist(epURL, tracklist);" beneath all of the if statements, but then it says it can't resolve "epURL". Seems stupid to write the same line 3 times!)
Updated 25/1 with current code:
final Handler uiHandler = new Handler();
final Button btnChooseEp = (Button)findViewById(R.id.btnChooseEp);
btnChooseEp.setEnabled(false);
btnChooseEp.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
builder.setTitle(getText(R.string.chooseEpisode));
builder.setItems(episodes2, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, final int pos)
{
replay.setVisibility(View.VISIBLE);
replayWeb.setVisibility(View.VISIBLE);
getTracklistProgressDialog = ProgressDialog.show(GA.this, "Please wait...",
"Retrieving tracklist...", true);
new Thread()
{
public void run()
{
try
{
String str1, epURL;
if(pos < 9)
{
str1 = getResources().getString(R.string.gaEpNo1);
epURL = String.format(str1, pos+1);
setTracklist2(epURL, tracklist);
}
else if(pos < 100)
{
str1 = getResources().getString(R.string.gaEpNo2);
epURL = String.format(str1, pos+1);
setTracklist2(epURL, tracklist);
}
else if(pos >= 100)
{
str1 = getResources().getString(R.string.gaEpNo3);
epURL = String.format(str1, pos+1);
setTracklist2(epURL, tracklist);
}
}
catch(Exception e)
{}
// Remove progress dialog
uiHandler.post(new Runnable()
{
public void run()
{
getTracklistProgressDialog.dismiss();
}
}
);
}
}.start();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
});
public void setTracklist2(final String string, final TextView tv)
{
try
{
uiHandler.post(
new Runnable()
{
public void run()
{
try
{
tv.setText(getStringFromUrl(string));
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
}
});
}
catch(Exception e)
{
e.printStackTrace();
}
}
Notes: "replay" and "replayWeb" are just two TextView's. "btnChooseEp" is enabled when another button is pressed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我的猜测是,您的行为很奇怪,因为您在非 ui 线程上调用 ui 方法。
getTracklistProgressDialog.dismiss();
必须在 ui 线程上执行。我的猜测是它正在崩溃,并且您的线程正在崩溃,然后使您的一些资源处于不良状态。这可以解释为什么你会得到不同数量的字符。
我会尝试在 onCreate 方法中创建一个最终的处理程序,它将绑定到 uiThread。在该线程中,您可以调用
This is fast, so it may not be not syntaxly, check your ide.
这是我能从你发布的内容中得到的最好的信息。如果您发布更多代码,我可以尝试运行它来为您提供更多帮助。
更新:
我想我发现了你的问题:
拥有另一个线程的想法是在那里完成长时间运行的工作,但我们现在所拥有的实际上是在 ui 线程上完成长时间运行的工作,这与我们的目标相反。我们需要做的是将 setTracklist 调用中对 getStringFromUrl(url) 的调用移至线程中。我将重写 setTracklist 如下:
然后在您的内部 onClick 方法中,执行以下操作:
我是这样,我们在重新获得 ui 线程执行之前调用 Web 服务/url。长时间运行的互联网检索在 bg 线程上运行,然后 ui 更新在 ui 线程上发生。认为这应该有帮助。
My guess is that you are getting bizarre behavior because you are invoking a ui method on a non-ui thread.
getTracklistProgressDialog.dismiss();
must be executed on a ui thread. My guess is that it is crashing and your thread is crashing then leaving some of your resources in a bad state. This would explain why you get a varying amount of characters.
I would try creating a final Handler in your onCreate method which would get bound to the uiThread. In that thread, you can then call
This is quick, so it may not be syntactically correct, check your ide.
This is the best i can get from what you've posted. If you post more of the code I can try to run it to give you more help.
Update:
I think I found your problem:
The idea of having another thread is to do the long running work there, but what we have right now actually does the long running work on the ui thread, the opposite of our goal. What we need to do is move the call to
getStringFromUrl(url)
from the setTracklist call up into the thread. I would rewrite setTracklist as follows:Then in your inner onClick method, do this:
I'm so, we make the call to the web service/url before we regain ui thread execution. The long running internet retrieval runs on the bg thread and then the ui update happens on the ui thread. Think this should help.