ProgressDialog problem during Activiy onCreate():void in Android
Solution:
Okay,I've found the solution from your answers since your answers are not completely working
First we need to use Handler
to post a Runnable
to main/UI thread to run UpdateDisplay()
and but define ProgressDialog
under UIThread not other threads which was also crucial.
Here is the final code :
public final String RSSFEEDOFCHOICE = "http://www.deals2buy.com/rssgen/tech.xml";
public final String tag = "RSSReader";
private RSSFeed feed = null;
private Handler 开发者_如何学JAVAhandler = new Handler();
private ProgressDialog dialog;
/** Called when the activity is first created. */
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
dialog = ProgressDialog.show(RSSReader.this, "Loading",
"Loading, please wait..");
Thread t = new Thread() {
public void run() {
feed = getFeed(RSSFEEDOFCHOICE);
handler.post(new Runnable() {
public void run() {
dialog.dismiss();
UpdateDisplay();
};
});
}
};
t.start();
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Problem :
When Android application first load, this is what happens :
- Retrieving RSS content from Url and parse it into
RSSFeed feed
instance variable viagetFeed(String url)
. - Showing these feeds to users in ListView via
UpdateDisplay()
method.
When these are happening, I wanted to show a ProgressDialog to users to notify them about system are retriving content like "Loading, please wait..." Once getFeed(String Url):RSSFeed
is done, ProgressDialog will be dismissed and UpdateDisplay():void
will be invoked.
So this is my first attempt :
public final String RSSFEEDOFCHOICE = "somewhere.xml"; //coming from http
public final String tag = "RSSReader";
private RSSFeed feed = null;
/** Called when the activity is first created. */
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
ProgressDialog dialog = ProgressDialog.show(RSSReader.this, "Loading...", "Loading, please wait");
feed = getFeed(RSSFEEDOFCHOICE);
dialog.dismiss();
UpdateDisplay();
}
And it doesn't show the ProgressDialog
so it didn't work the way I want. Since I belived it is because ProgressDialog is continues progress, it should be handled by another Thread
.
Here is my second attempt :
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
Thread t = new Thread()
{
public void run()
{
ProgressDialog dialog = ProgressDialog.show(RSSReader.this, "Loading...", "Loading, please wait");
feed = getFeed(RSSFEEDOFCHOICE);
dialog.dismiss();
}
};
UpdateDisplay();
}
It was okay till UpdateDisplay()
since this method was handled by main thread and it wasn't waiting anything so I thought maybe I should have put it under t
Thread after dialog.dismiss()
.
So I did this :
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
Thread t = new Thread()
{
public void run()
{
ProgressDialog dialog = ProgressDialog.show(RSSReader.this, "Loading...", "Loading, please wait");
feed = getFeed(RSSFEEDOFCHOICE);
dialog.dismiss();
UpdateDisplay();
}
};
}
But then debugger said at run-time : only the main thread which handles onCreate():void
can reach and use View objects because it creates them.
Now, I am so messed up and feel like quitting programming.
Some one can help me :/
Thanks in advance.
You could use AsyncTask, thats exactly what its for. Since onPostExecute(Long result) is done on the UI thread, it wont crash when looking for View objects.
Here is a example taken from the asyncTask reference
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
What you want to do is obtain the RSS feed in doInBackground(), and then update the UI in onPostExecute.
In your onCreate() method, invoke the asyncTask.
new DownloadFilesTask().execute(url1, url2, url3);
Okay,I've found the solution from your answers since your answers are not completely working
First we need to use Handler
to post a Runnable to main/UI thread to run UpdateDisplay()
and but define ProgressDialog
under UIThread
not other threads which was also crucial.
Here is the final code :
public final String RSSFEEDOFCHOICE = "http://www.deals2buy.com/rssgen/tech.xml";
public final String tag = "RSSReader";
private RSSFeed feed = null;
private Handler handler = new Handler();
private ProgressDialog dialog;
/** Called when the activity is first created. */
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
dialog = ProgressDialog.show(RSSReader.this, "Loading",
"Loading, please wait..");
Thread t = new Thread() {
public void run() {
feed = getFeed(RSSFEEDOFCHOICE);
handler.post(new Runnable() {
public void run() {
dialog.dismiss();
UpdateDisplay();
};
});
}
};
t.start();
}
You have to run your request in another thread than the progressdialog. So try with
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
ProgressDialog dialog = ProgressDialog.show(RSSReader.this, "Loading...", "Loading, please wait");
Thread t = new Thread()
{
public void run()
{
feed = getFeed(RSSFEEDOFCHOICE);
dialog.dismiss();
UpdateDisplay();
}
};
}
And depending on what you do in update display you should run it in the UI thread.
Actually the best way would be to use AsyncTask
.
However as a quick workaround you could do smth like this:
private Handler handler = new Handler();
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
Thread t = new Thread()
{
public void run()
{
ProgressDialog dialog = ProgressDialog.show(RSSReader.this, "Loading...", "Loading, please wait");
feed = getFeed(RSSFEEDOFCHOICE);
dialog.dismiss();
handler.post(new Runnable() {
public void run() {
UpdateDisplay();
}
});
}
};
}
精彩评论