Reputation: 6476
I am trying to fetch data from internet, parse it and then show the data to the user. The action usually takes 3 seconds or so, and I would like to a spinner ProgressDialog show a message saying that I am loading data. The problem is that ProgressDialog only shows up when the loading is almost complete. This is my code
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button load_routes = (Button)findViewById(R.id.load_routes);
load_routes.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
task_complete = false;
progressBar = new ProgressDialog(v.getContext());
progressBar.setCancelable(false);
progressBar.setMessage("Fetching routes data ...");
progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressBar.show();
if(haveNetworkConnection())
{
loading_routes_data(v);
}
else
{
progressBar.dismiss();
}
}
});
}
And this is my function that gets called onclick
private void loading_routes_data(View v)
{
try
{
new Thread(new Runnable()
{
public void run()
{
while(!task_complete)
{
refresh_routes();
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
runOnUiThread(new Runnable()
{
public void run()
{
progressBar.dismiss();
}
});
}
}).start();
}
catch(Exception e)
{
}
while(!task_complete)
{
}
}
My refresh_routes()
function gets the data, parses it and then sets task_complete
to true
, I am not even sure on whether or not I should keep it inside the while loop.
So that is my huge problem. I would like to display ProgressDialog
right away on button click, then I would like to call refresh_routes()
, and once refresh_routes()
is complete I would like to get rid of progress dialog. But I am unsure as to how to go about doing that.
If someone could show me how to go about solving the problem with some article as an example or something like that I will be really grateful. Thank you in advance :)
Upvotes: 0
Views: 1066
Reputation: 31283
You're locking the UI thread by calling while(!task_complete)
at the end of your method. You really should be using an AsyncTask
for an operation like this. Here's what your AsyncTask
should look like:
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog progressDialog;
private Context context;
public MyAsyncTask(Context context) {
this.context = context;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show( context, null, "Fetching routes data ..." );
}
@Override
protected Void doInBackground( Void... params ) {
while (!task_complete) {
refresh_routes();
try {
Thread.sleep( 1000 );
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPostExecute( Void result ) {
super.onPostExecute( result );
progressDialog.dismiss();
}
}
To execute this, you would do this:
new MyAsyncTask( this ).execute();
I'm not sure how your refresh_routes()
method works, but you might consider moving it's functionality inside the doInBackground()
method.
Upvotes: 2