I have a Async Task that does not add the percentage while it is going through the task. It always stays at 0% 0/100
Here is my code
private class getAppInfo extends AsyncTask<String, String, String> {
/** The system calls this to perform work in a worker thread and
* delivers it the parameters given to AsyncTask.execute() */
ProgressDialog dialog;
#Override
protected void onPreExecute() {
if(showLoading == true){
dialog = new ProgressDialog(SelfHelp.this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMessage("Loading");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.setMax(100);
dialog.setProgress(100);
dialog.show();
}
}
#Override
protected String doInBackground(String... urls) {
String xml = null;
int count = 0;
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(urls[0]);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
xml = EntityUtils.toString(httpEntity);
while(count != 100){
publishProgress(""+count);
count += 5;
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Document doc = parser.GetDomElement(xml);
NodeList nl = doc.getElementsByTagName("topic");
getChildElements(nl);
return xml;
}
#Override
protected void onProgressUpdate(String... progress) {
Log.v("count",progress[0]);
dialog.setProgress(Integer.parseInt(progress[0]));
}
/** The system calls this to perform work in the UI thread and delivers
* the result from doInBackground() */
#Override
protected void onPostExecute(String result) {
//dialog.setProgress(100);
menuList.setAdapter(setListItems(menuItems));
menuList.setTextFilterEnabled(true);
if(showLoading == true){
dialog.dismiss();
showLoading = false;
}
}
It does go into onProgressUpdate and the count goes up by 5 but the progress bar does not change. How can I have it increment by 5 and show the progress properly?
Your issue is related to setIndeterminate(true): You should set it to false if you want to have progress update. if you setIndeterminate(true) then the ProgressDialog will work as the classic Windows Hourglass
You can try following code, It is showing progress in % ratio, here is the code,
public class ProgressBarExampleActivity extends Activity
{
ProgressThread progThread;
ProgressDialog progDialog;
Button button1, button2;
int typeBar; // Determines type progress bar: 0 = spinner, 1 = horizontal
int delay = 1000; // Milliseconds of delay in the update loop
int maxBarValue = 30; // Maximum value of horizontal progress bar
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// // Process button to start spinner progress dialog with anonymous inner class
// button1 = (Button) findViewById(R.id.Button01);
// button1.setOnClickListener(new OnClickListener()
// {
// public void onClick(View v)
// {
// typeBar = 0;
// showDialog(typeBar);
// }
// });
// Process button to start horizontal progress bar dialog with anonymous inner class
button2 = (Button) findViewById(R.id.Button02);
button2.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
typeBar = 1;
showDialog(typeBar);
}
});
}
// Method to create a progress bar dialog of either spinner or horizontal type
#Override
protected Dialog onCreateDialog(int id)
{
switch(id)
{
// case 0: // Spinner
// progDialog = new ProgressDialog(this);
// progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
// progDialog.setMessage("Loading...");
// progThread = new ProgressThread(handler);
// progThread.start();
// return progDialog;
case 1: // Horizontal
progDialog = new ProgressDialog(this);
progDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progDialog.setMax(maxBarValue);
progDialog.setMessage("Dollars in checking account:");
progThread = new ProgressThread(handler);
progThread.start();
return progDialog;
default:
return null;
}
}
// Handler on the main (UI) thread that will receive messages from the
// second thread and update the progress.
final Handler handler = new Handler()
{
public void handleMessage(Message msg)
{
// Get the current value of the variable total from the message data
// and update the progress bar.
int total = msg.getData().getInt("total");
progDialog.setProgress(total);
// if (total >= maxBarValue)
if (total <= 0 )
{
dismissDialog(typeBar);
progThread.setState(ProgressThread.DONE);
}
}
};
// Inner class that performs progress calculations on a second thread. Implement
// the thread by subclassing Thread and overriding its run() method. Also provide
// a setState(state) method to stop the thread gracefully.
private class ProgressThread extends Thread
{
// Class constants defining state of the thread
final static int DONE = 0;
final static int RUNNING = 1;
Handler mHandler;
int mState;
int total;
// Constructor with an argument that specifies Handler on main thread
// to which messages will be sent by this thread.
ProgressThread(Handler h)
{
mHandler = h;
}
// Override the run() method that will be invoked automatically when
// the Thread starts. Do the work required to update the progress bar on this
// thread but send a message to the Handler on the main UI thread to actually
// change the visual representation of the progress. In this example we count
// the index total down to zero, so the horizontal progress bar will start full and
// count down.
#Override
public void run()
{
mState = RUNNING;
total = maxBarValue;
while (mState == RUNNING)
{
// The method Thread.sleep throws an InterruptedException if Thread.interrupt()
// were to be issued while thread is sleeping; the exception must be caught.
try
{
// Control speed of update (but precision of delay not guaranteed)
Thread.sleep(delay);
} catch (InterruptedException e) {
Log.e("ERROR", "Thread was Interrupted");
}
// Send message (with current value of total as data) to Handler on UI thread
// so that it can update the progress bar.
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
b.putInt("total", total);
msg.setData(b);
mHandler.sendMessage(msg);
total--; // Count down
}
}
// Set current state of thread (use state=ProgressThread.DONE to stop thread)
public void setState(int state)
{
mState = state;
}
}
}
See the output,
I will mention another aproach, because I came across this solution when I was looking for some practical way how to communicate from my Service running AsyncTask back to main UI. Lucifer's solution is not modular for Services, if you need to use your Service in more then 1 class (that was my case), you won't be able to access variable handler and as far as I know you can't even send Handler as Intent to Service (you can send it to AsyncTask tho). Solution is broadcasting.
sendBroadcast(new Intent(WORK_DONE));
in AsyncTask and
private BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context c, Intent i) { //update your UI here }
}
registerReceiver(receiver, new IntentFilter(WORK_DONE));
in your activity.
I don't like all those inner classes android developers use. I understand it's easier to create inner class and access outer class variables, but once you need to use the class again your doomed and you have to edit the code! I am realy new to Android, maybe I am wrong and you actually don't need to reuse those classes. Never did a bigger project so I have no idea but it just doesn't feel right, since on college, they tried hard to teach us how to programm reusable code.
Related
my app does heavy task so I want to show a progress bar to user and run the task in background, so user can understand that its loading.
when the background task completes hide the progress bar.
But progress bar should not take same time to reach its max, it should be dependent on users input or processing.
Use AsyncTask. AsyncTask is one of the easiest ways to implement parallelism in Android without having to deal with more complex methods like Threads. Though it offers a basic level of parallelism with the UI thread, it should not be used for longer operations (of, say, not more than 2 seconds).
AsyncTask has four methods do the task:
onPreExecute()
doInBackground()
onProgressUpdate()
onPostExecute()
Check link for more details.
You can create something like this, the process ends in 30 seconds. I hope it will be useful to you
private ProgressDialog progressDialog;
public void init() {
progressDialog = new ProgressDialog(context);
progressDialog.setCancelable(false);
progressDialog.setMessage("please wait");
progressDialog.show();
new Thread(new Runnable() {
#Override
public void run() {
while (time < 30) {
try {
Thread.sleep(1000);
Message message = new Message();
message.what = UPDATE_PROGRESS;
handler.sendMessage(message);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Message message = new Message();
message.what = END_PROGRESS;
handler.sendMessage(message);
}
}).start();
}
private static final int UPDATE_PROGRESS = 1;
private static final int END_PROGRESS = 2;
private int time;
private Handler handler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case UPDATE_PROGRESS:
progressDialog.setMessage("Time: " + time++);
break;
case END_PROGRESS:
progressDialog.dismiss();
break;
default:
break;
}
return true;
}
});
UPDATE
This is the thread and handler example. But you can also create an asynctask
I am dealing with the android UI and I am facing what looks a very common problem here. By using an AsyncTask, I want to:
1- Show a ProgressDialog meanwhile some stuff gets ready
2- Show a countdown to let the user get ready for the real action
3- Play a sound afterwards the countdown to notify the sample will be taken
4- Show another ProgressDialog representing the 10s sample taking
5- Play a sound afterwards the sample is taken
Well, this is my outcome:
1- Works fine
2- MISSING, THE UI IS NOT UPDATED BUT THE BACKGROUND PROCESS IS RUNNING
3- Works fine
4- Works fine
5- Works fine
The funniest is, when I remove the code to handle the first part that handles the first progress dialog, the other parts are executed/displayed as expected. I understand there is something blocking the UI at some point but I am quite newbie with android to realize what's blocking it.
Thanks in advance for your help.
public class SnapshotActivity extends AppCompatActivity {
private int COUNTDOWN_TIME = 5;
private Button startStop;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_snapshot);
startStop = (Button) findViewById(R.id.btnStartStop);
startStop.setText("START");
}
public void startSnapshot(View view) {
startStop.setClickable(false);
new Async(SnapshotActivity.this).execute();
}
class Async extends AsyncTask<Void, Void, Void>{
TextView tv = (TextView) findViewById(R.id.tvCountDown);
ProgressDialog progressDialog ;
ProgressDialog preparing;
Context context;
int flag = 0;
int counter = COUNTDOWN_TIME;
public Async(Context context) {
this.context = context;
progressDialog = new ProgressDialog(context);
preparing = new ProgressDialog(context);
}
#Override
protected void onPreExecute(){
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
//PROGRESS DIALOG
flag = 4;
publishProgress();
try {
//SIMULATE SOME WORKLOAD
Thread.sleep(2000);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
flag = 5;
publishProgress();
//HANDLE THE COUNTDOWN
for(counter = COUNTDOWN_TIME; counter>=1; counter--){
publishProgress();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
//PLAY THE SOUND
new Thread(new Runnable() {
#Override
public void run() {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
}
}).start();
//PROGRESS DIALOG
flag = 1;
publishProgress();
//10s SAMPLE
flag = 2;
for(int j = 0; j <= 10; j++ ){
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
publishProgress();
}
//PLAY THE SOUND
new Thread(new Runnable() {
#Override
public void run() {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
}
}).start();
flag = 3;
publishProgress();
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
switch (flag) {
case 0:
tv.setText(String.valueOf(counter));
break;
case 1:
tv.setText("");
progressDialog.setTitle("TAIKING SAMPLE");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMax(10);
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.show();
break;
case 2:
progressDialog.incrementProgressBy(1);
break;
case 3:
progressDialog.dismiss();
break;
case 4:
preparing.setMessage("Starting the device...");
preparing.setCanceledOnTouchOutside(false);
preparing.show();
break;
case 5:
preparing.dismiss();
break;
default:
break;
}
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
startStop.setClickable(true);
}
}
}
There are two issues:
You are not informing onProgressUpdate() of the countdown value
There is a race condition
doInBackground() and onProgressUpdate() methods are executed in two different threads and both methods/threads are accessing the flag field in a unsafe way. Instead of setting a value in flag in doInBackground() to be read in onProgressUpdate(), you can inform this value directly in the publishProgress() call. So I advise you to do the following:
public class SnapshotActivity extends AppCompatActivity {
// ...
// Change the Progress generic type to Integer.
class Async extends AsyncTask<Void, Integer, Void> {
// Remove the flag field.
// int flag = 0;
#Override
protected Void doInBackground(Void... params) {
//PROGRESS DIALOG
// Pass the flag argument in publishProgress() instead.
// flag = 4;
publishProgress(4);
// ...
// flag = 5;
publishProgress(5);
//HANDLE THE COUNTDOWN
for (counter = COUNTDOWN_TIME; counter>=1; counter--){
// The countdown progress has two parameters:
// a flag indicating countdown and
// the countdown value.
publishProgress(6, counter);
// ...
}
//PLAY THE SOUND
// ...
//PROGRESS DIALOG
// flag = 1;
publishProgress(1);
//10s SAMPLE
// flag = 2;
for(int j = 0; j <= 10; j++ ){
// ...
publishProgress(2);
}
//PLAY THE SOUND
// ...
// flag = 3;
publishProgress(3);
return null;
}
// This signature changes.
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
// Redeclare flag here.
int flag = values[0];
switch (flag) {
// ...
case 6:
tv.setText(Integer.toString(values[1]));
break;
// ...
}
}
}
}
I want to create a dialogBuilder with a text field and a button on it. The idea is to make the program wait for any further actions until the text in the field is entered and the OK button is clicked. Below is the code:
private static final Object wait = new int[0];
private static String result = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Handler h = new Handler();
final Context context = MainActivity.this;
h.post(new Runnable() {
public void run() {
final Builder dialogBuilder = new AlertDialog.Builder(context);
dialogBuilder.setTitle(R.string.app_name);
final LinearLayout panel = new LinearLayout(context);
panel.setOrientation(LinearLayout.VERTICAL);
final TextView label = new TextView(context);
label.setId(1);
label.setText(R.string.app_name);
panel.addView(label);
final EditText input = new EditText(context);
input.setId(2);
input.setSingleLine();
input.setInputType(InputType.TYPE_CLASS_TEXT
| InputType.TYPE_TEXT_VARIATION_URI
| InputType.TYPE_TEXT_VARIATION_PHONETIC);
final ScrollView view = new ScrollView(context);
panel.addView(input);
view.addView(panel);
dialogBuilder
.setCancelable(true)
.setPositiveButton(R.string.app_name,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
result = input.getText().toString();
synchronized (wait) {
wait.notifyAll();
}
dialog.dismiss();
}
}).setView(view);
dialogBuilder.setOnCancelListener(new OnCancelListener() {
public void onCancel(DialogInterface arg0) {
result = null;
synchronized (wait) {
wait.notifyAll();
}
}
});
dialogBuilder.create().show();
}
});
String localResult = null;
try {
synchronized (wait) {
Log.d("Waiting", "Waiting " + localResult);
wait.wait();
}
localResult = result;
result = null;
if (localResult == null) {
// user is requesting cancel
throw new RuntimeException("Cancelled by user");
}
Log.d("RESULT ", "RESULT " + localResult);
} catch (InterruptedException e) {
localResult = result;
result = null;
if (localResult == null) {
// user is requesting cancel
Log.d("CANCELED ", "CANCELED " + localResult);
throw new RuntimeException("Cancelled by user");
}
}
Log.d("RESULT AFTER THE DIALOG", "RESULT AFTER THE DIALOG " + result);
}
The program is going to Log.d("Waiting", "Waiting " + localResult); and after that just waiting. NO DIALOG BUILDER IS SHOWN on the activity window. I used the debug mode and saw that the program flow is not entering the run() method, but the value of the Handler.post() is true. And for this reason the dialog is not shown, and the program is waiting.
I have tried to remove the moment with waiting (remove the Handler.post()), just to see if the dialog will show, and it showed and all moved well, but the result was not I am needing - I want the program to wait the input from the dialog ... I am really out of ideas.
Would you please give me some suggestions as I am really out of ideas.
Thanks a lot!
Handlers don't run in a separate thread. So when you call wait() :
synchronized (wait) {
Log.d("Waiting", "Waiting " + localResult);
wait.wait();
}
It waits indefinitely since the handler runs on the same thread as the current thread. Your Runnable can only be executed after the onCreate() method finishes but this will never happen because you just called wait().
You should reconsider your idea and find a workaround (for example, show the dialog the usual way and disable the "OK" button as long as the user does not enter a valid text). But calling wait() on the UI thread cannot go well.
You should be running the display of the Dialog in the UI Thread, not a seperate thread.
An example would be something like this:
In the onCreate()
runOnUiThread(new Runnable() {
#Override
public void run() {
// Display progress dialog when loading contacts
dialog = new ProgressDialog(this);
// continue with config of Dialog
}
});
// Execute the Asynchronus Task
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
// code to execute in background
return null;
}
#Override
protected void onPostExecute(Void result) {
// Dismiss the dialog after inBackground is done
if (dialog != null)
dialog.dismiss();
super.onPostExecute(result);
}
}.execute((Void[]) null);
Specifically what is happening here is the Dialog is being displayed on the UI thread and then the AsyncTask is executing in the background while the Dialog is running. Then at the end of the execution we dismiss the dialog.
I'm trying to write code to pull a server every second for updated messages. The messages then get displayed in a text view. If I do not change the text in the text view it runs fine. It will crash if I try to change the textview on the thread. IF i change it not on the thread works fine.
I'm assuming the thread cannot access the main threads memory? How can I set the text in the view with the text just loaded over the internet?
In the code below I have a thread that does a endless loop with a sleep. It calls a method called SendMessage. Send Message loads in text over the internet and at the end tries to update the View with it. It causes a exception when this happens.
code:
public class cChat extends cBase implements OnClickListener {
/** Called when the activity is first created. */
TextView mUsers;
TextView mComments;
int i=0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chat);
mUsers=( TextView) findViewById(R.id.viewusers);;
mComments=( TextView) findViewById(R.id.viewchats);;
Thread thread = new Thread()
{
#Override
public void run() {
try {
int t=0;
while(true)
{
SendMessage();
sleep(1000*5);
t++;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}
public void onClick(View v) {
} // end function
// send a uypdate message to chat server
// return reply in string
void SendMessage()
{
try {
URL url = new URL("http://50.63.66.138:1044/update");
System.out.println("make connection");
URLConnection conn = url.openConnection();
// set timeouts to 5 seconds
conn.setConnectTimeout(1000*5);
conn.setReadTimeout(5*1000);
conn.setDoOutput(true);
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
// String line;
String strUsers=new String("");
String strComments=new String("");
String line=new String();
int state=0;
while ((line= rd.readLine() ) != null) {
switch(state){
case 0:
if ( line.contains("START USER"))
state=1;
if ( line.contains("START COMMENTS"))
state=2;
break;
case 1:
if ( line.contains("END USER"))
state=0;
else
{
strUsers+=line;
strUsers+="\n";
}
break;
case 2:
if ( line.contains("END COMMENTS"))
state=0;
else {
strComments+=line;
strComments+="\n";
}
break;
} // end switch
} // end loop
// the next line will cause a exception
mUsers.setText(strUsers);
mComments.setText(strComments);
} catch (Exception e) {
i++; // use this to see if it goes here in debugger
// System.out.println("exception");
// System.out.println(e.getMessage());
}
} // end methed
}
use runOnUiThread as
YOUR_CURRENT_ACTIVITY.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// the next line will cause a exception
mUsers.setText(strUsers);
mComments.setText(strComments);
//....YOUR UI ELEMENTS
}
});
EDIT :
see doc runOnUiThread
You can use a handler to post tasks (Runnables) to the UI/Main Thread:
private Handler handler = new Handler();
//...
Thread thread = new Thread()
{
#Override
public void run() {
try {
int t=0;
while(true)
{
handler.post(new Runnable() {
#Override
public void run() {
SendMessage();
}
});
sleep(1000*5);
t++;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
You can't touch an UI widget from a thread different than the one used to create it (the UI thread). But if you have a reference to the Activity, you can simply do:
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
mUsers.setText(strUsers);
mComments.setText(strComments);
}
});
which would require strUsers to be accessible by the anonymous class. For that you can simply do:
final String finalUseres = strUsers;
and use finalUsers within run().
Try using a Service to continuously pull/send data to server. This will reduce the load on your UI-Thread.
the Andoid UI toolkit is not thread-safe. So, you
must not manipulate your UI from a worker thread
To fix this problem, Android offers several ways to access the UI thread from other threads. Here is a list of methods that can help:
Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable, long)
you can also use AsyncTask.
see this tutorial on process and threads in android.
I have written progress bar when I consume WCF part. I have to know after get response it need to dismiss.
ProgressThread progThread;
ProgressDialog progDialog;
int typeBar; // Determines type progress bar: 0 = spinner, 1 = horizontal
int delay = 40; // manually define thedelay
int maxBarValue = 200; // manually define the maximum value
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case 0:
typeBar = 0;
showDialog(typeBar);
return true;
case 1:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
protected Dialog onCreateDialog(int id) {
// Spinner
progDialog = new ProgressDialog(this);
progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progDialog.setMessage("Loading...");
progThread = new ProgressThread(handler);
progThread.start();
return progDialog;
}
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
int total = msg.getData().getInt("total");
progDialog.setProgress(total);
if (total <= 0){
dismissDialog(typeBar);
progThread.setState(ProgressThread.DONE);
}
}
};
This is thread class
private class ProgressThread extends Thread {
final static int DONE = 0;
final static int RUNNING = 1;
Handler mHandler;
int mState;
int total;
ProgressThread(Handler h) {
mHandler = h;
}
#Override
public void run() {
mState = RUNNING;
total = maxBarValue;
while (mState == RUNNING) {
try {
loadDownloadData();
Thread.sleep(delay);
} catch (InterruptedException e) {
Log.e("ERROR", "Thread was Interrupted");
}
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
b.putInt("total", total);
msg.setData(b);
mHandler.sendMessage(msg);
total--;
}
}
public void setState(int state) {
mState = state;
}
}
WCF call method is loadDownloadData(); , Where want to call & how we can define the time frame for sleep, after getting response only it need to dismis this progress bar...
Please help me
Thanks in advance.
What exactly should your method do?
At the moment it looks like you are calling some method in loop and after that you sleep a thread. If your loadDownloadData calls the WCF it will be called in each cycle? If it doesn't start asynchronous processing it will wait until the method completes and only after that it will continue to sleeping the thread.
If you want to have progress bar for downloading content over WCF you cannot use such approach. First the whole WCF call must run asynchronously. Next you need to know amount of downloaded data upfront and you need to read data continuously - only that will allow you to control real progress bar. Normal HTTP processing will write all data to the server, pass them to the network, load all data to the buffer on the client and after that your method return the result - from client API such operation is atomic (= you cannot measure progress). This is usually avoided by chunked data where server pushes data in chunks and client is able to read these chunks like a stream. In WCF it is performed by streaming transfer mode.
At the moment you should simply use some unlimited spinner and wait for operation to complete.