I updated my code like Andro wrote about to me:
public class ZiiziiActivity extends Activity {
ProgressDialog pd;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pd = new ProgressDialog(ZiiziiActivity.this);
final Handler handler = new Handler()
{
public void handleMessage(Message msg)
{
if(msg.what==0)
{
pd.dismiss();
}
}
};
Button end = (Button) findViewById(R.id.button2);
end.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("Working...");
pd.setIndeterminate(true);
pd.setCancelable(false);
pd.show();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
for (int i=0;i<1000000;i++)
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //To denote a delay in background processing
}
handler.sendEmptyMessage(0);
}
}); t.start();
}
});
}
}
But when the progress start, it never ends.
What can be wrong?
This is so simple. The basic fact behind this is as follows.
Your progress dialog runs in the main UI. Your for loop here gets executed so soon and takes more priority and hence you are not able to see your progress dialog but the fact is, your code works fine and progress dialog does show up for fraction of seconds which the human eye can't catch.
Usually people use a progress dialog when they do something in the background thread and not the main thread. So you will have to change a little bit of your code. They are,
1) Surround your for loop with a thread like this,
Button end = (Button) findViewById(R.id.button2);
end.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
ProgressDialog pd = new ProgressDialog(ZiiziiActivity.this);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("Working...");
pd.setIndeterminate(true);
pd.setCancelable(false);
pd.show();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
for (int i=0;i<1000000;i++)
{
Thread.sleep(100); //To denote a delay in background processing
}
handler.sendEmptyMessage(0);
}
});
t.start();
}
});
2) Now add a handler to your onCreate() like this:
handler = new Handler()
{
public void handleMessage(Message msg)
{
if (msg.what == 0)
{
pd.dismiss();
}
};
Note that you can't update your UI from a background thread. So in order to update the UI from some other worker thread you go for handlers. So once your for loop gets completed, a call will be made to handlers which updates the UI. (In this case it cancels the progress dialog).
Your code is the same as you would do the following.
pd.show();
pd.dismiss();
The method show gets called, but immediately the dialog will be dismissed because your for loop is not time comsuming at all. In addition, you are blocking the UI. So if you replace your empty for loop through a time-consuming operation, your progress won't run because you block the UI thread.
Related
I am new to Android dev, and am trying to solve this problem that has been giving me some frustration. I am trying to close this progressDialog. When I run the app, it displays, the information is fetched, and the UI is updated. However, the dialog is never dismissed.
progDialog = ProgressDialog.show(HomeActivity.this, "", "Fetching info...", true, false);
new Thread(new Runnable() {
public void run() {
fetchInfomation(userID); //fetches information - Works
runOnUiThread(new Runnable() {
public void run() {
setLayoutList(); //updates UI - Works
progDialog.dismiss(); //doesn't seem to close progress dialog
firstView(); //displays prompt - Works
}
});
progDialog.dismiss(); //doesn't close dialog either
}
}).start();
Any ideas?
You can't interact with UI inside an external thread. There is some techniques to do that but it's not necessary.
You can use Handler.
For example:
...
private Handler mHandler;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
mHandler = new Handler() {
#Override
public void handleMessage (Message msg) {
switch (msg.what) {
case 0: ...
case 1: ...
}
}
}
}
And:
....
new Thread() {
#Override
public void run() {
... // do your background jobs here
mHandler.sendEmptyMessage(...); // interact with UI
});
}
}.start();
It will be good practice if you do any GUI updates on UI thread. Inside any thread you can run your UI thread where you can do the UI stuffs or else you can go for message handler also which will do the same for you.
Runnable run_in_ui = new Runnable() {
#Override
public void run() {
// do your UI stuffs here
}
};
runOnUiThread(run_in_ui);
I am having problems getting the ProgressDialog wheel spinning. Here is my code:
final ProgressDialog dialog = ProgressDialog.show(this, "", "Loading...", true, false);
Thread thread=new Thread(new Runnable(){
public void run(){
runOnUiThread(new Runnable(){
#Override
public void run() {
if(dialog.isShowing())
// starts a foreground service, does database stuff,
// sets up a spinner with values
dialog.dismiss();
}
});
}
});
thread.start();
Everything goes as planned, I get the ProgressDialog, stuff happens in the background and once set, ProgressDialog goes away - the only problem is that the animation in ProgressDialog is not spinning, pretty much rendering it useless.
What am I doing wrong?
The code you omitted here
// starts a foreground service, does database stuff,
// sets up a spinner with values
must do something that block the UI thread. Just put them outside the runOnUiThread() Method.
Thread thread=new Thread(new Runnable(){
public void run(){
// starts a foreground service, does database stuff,
// sets up a spinner with values
runOnUiThread(new Runnable(){
#Override
public void run() {
if(dialog.isShowing())
dialog.dismiss();
}
});
}
});
ProgressDialog example using handler android
final ProgressDialog dialog = ProgressDialog.show(this, "Title",
"Message", true);
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
dialog.dismiss();
}
};
Thread t = new Thread() {
public void run() {
// write process code here.
handler.sendEmptyMessage(0);
}
};
t.start();
Fix issue: ProgressDialog not working
Because you put the processing dialog in to wrong area, for example with my error:
I have a two activities: MainActivity and ShowingActivity, MainActivity will show processing dialog after new intent tranfer to ShowingActivity and ShowingActivity will get some DATA from server (it will be blocked here). When I call ProcessingDialog in MainActivity, it showed but not spinning because my Intent move to ShowingActivity and it block Ui because action of get DATA from server must wait some seconds. So I fixed it:
1/ in MainActivity call:
final Intent working = new Intent(getApplicationContext(),
WorkingActivity.class);
final ProgressDialog ringProgressDialog = ProgressDialog.show(
MainActivity.this, "Please wait ...", "Connecting ...",
true);
ringProgressDialog.setCancelable(false);
new Thread(new Runnable() {
#Override
public void run() {
//Menthod need time to load:
getDatafromServer();
if (BookListFragment.isLoaded) {
ringProgressDialog.dismiss();
startActivity(working);
return;
}
});
So it will not block Ui because MainActivity still runing after DATA was gotten.
And in ShowingActivity I will use this DATA (because I set DATA is a static String).
I have created a ProgressDialog in android and it works when I do a simple example.
For example, this works.
public void onClick(View v)
{
// Perform action on click
System.out.println("Progess Bar");
final ProgressDialog myProgressDialog = ProgressDialog.show(AndroidTestApplicationActivity.this,
"Please wait...", "Getting updates...", true);
new Thread()
{
public void run()
{
try
{
// Do some Fake-Work
sleep(5000);
}
catch (Exception e)
{
}
// Dismiss the Dialog
myProgressDialog.dismiss();
}
}.start();
}
But once I add in a reference to my custom class, it just stops running this new thread.
button1.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
// Perform action on click
System.out.println("Progess Bar");
// Display an indeterminate Progress-Dialog
final ProgressDialog myProgressDialog = ProgressDialog.show(AndroidTestApplicationActivity.this,
"Please wait...", "Getting Updates...", true);
new Thread()
{
public void run()
{
try
{
HealthySubObject hsObject = new HealthySubObject();
// Do some more work with my hsObject - nothing happens after this point.
sleep(5000);
}
catch (Exception e)
{
}
// Dismiss the Dialog
myProgressDialog.dismiss();
}
}.start();
}
});
What happens is that as soon as I click this button, the progress dialog flashes up on the screen real quick and then disappears. But if you look at my code, it should wait 5 seconds before disappearing. I have put debug statements before and after the reference to my custom class and I can see the statements before but not the ones after. Does anyone have any idea why that is happening? As long as my class is public I should be able to call it from a new thread, right?
I am still pretty new to android and this is my first adventure into multi-threaded android apps. Any help would be much appreciated.
SOLUTION
Thanks for your help everyone. It is working now.
button1.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
// Perform action on click
System.out.println("Progess Bar");
//ProgressDialog dialog = ProgressDialog.show(AndroidTestApplicationActivity.this, "", "Loading. Please wait...", true);
// Display an indeterminate Progress-Dialog
final ProgressDialog myProgressDialog = ProgressDialog.show(AndroidTestApplicationActivity.this,
"Please wait...", "Doing Extreme Calculations...", true);
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run()
{
HealthySubObject hsObject = new HealthySubObject();
ArrayList<HashMap<String, String>> onlineDB = hsObject.jsonToArray();
//
// more stuff goes here.
//
//
myProgressDialog.dismiss();
}
}, 1500);
}
});
I would really recommend to use Handler instead of Thread. Using the Thread.sleep method is actually discouraged. Something like this is much better:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
HealthySubObject hsObject = new HealthySubObject();
myProgressDialog.dismiss();
}
}, 5000);
The problem is that you need to be on the UI thread to do modify the UI, and inside the run() method of your Thread you are in a "background" thread. Try using a handler inside your thread when you need to access the UI thread.
final ProgressDialog Pdialog = ProgressDialog.show(SpinnerClass.this, "",
"Loading. Please wait...", true);
Thread ProgressThread = new Thread() {
#Override
public void run() {
try {
sleep(3000);
Pdialog.dismiss();
} catch(InterruptedException e) {
// do nothing
} finally {
}
}
};
ProgressThread.start();
TabHost1 TabHost1Object2 = new TabHost1();
TabHost1Object2.tabHost.setCurrentTab(2);
The problem I have with this thread is that it sets the current tab before the progress dialog starts. What have i done wrong ?
I want the dialog to run and dismiss, and after thread is done set tab.
use AsyncTask for this
some hints:
public class BackgroundAsyncTask extends AsyncTask<Void, Integer, Void> {
int myProgress;
#Override
protected void onPostExecute(Void result) {
TabHost1 tab = new TabHost1();
tab.tabHost.setCurrentTab(2);
progressBar.dismiss();
}
#Override
protected Void doInBackground(Void... params) {
while(myProgress<100){
myProgress++;
publishProgress(myProgress);
SystemClock.sleep(100);
}
return null;
}
#Override
protected void onProgressUpdate(Integer p) {
progressBar.setProgress(p);
}
}
The thing is that,you are starting a thread which will not affect your main UI. So what eventually happens is that, your thread will run separately which will now allow the next lines of your code to be executed. So in your case,
TabHost1 TabHost1Object2 = new TabHost1();
TabHost1Object2.tabHost.setCurrentTab(2);
these lines will be executed irrespective to your thread which is also getting executed simultaneously. So what you can do here is you can either go for AsyncTask or create handlers to handle this part of your code. You have to change your code like this.
Do this in your onCreate()
Handler handler;
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
if (msg.what == 0) {
Pdialog.dismiss();
TabHost1 TabHost1Object2 = new TabHost1();
TabHost1Object2.tabHost.setCurrentTab(2);
}
};
And now in your thread,call the handler like this,
final ProgressDialog Pdialog = ProgressDialog.show(SpinnerClass.this, "",
"Loading. Please wait...", true);
Thread ProgressThread = new Thread() {
#Override
public void run() {
try {
sleep(3000);
} catch(InterruptedException e) {
// do nothing
} finally {
handler.sendEmptyMessage(0);
}
}
};
this will allow your tabhost to wait until the thread gets executed and will come into view after thread finishes execution.
Here is the problem
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
progressDialog = ProgressDialog.show(ContactMainActivity.this, "",
"Loading. Please wait...",true);
setContentView(R.layout.contactlist);
contactListView=getListView();
contactListView.setTextFilterEnabled(true);
contactListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
Thread t = new Thread() {
public void run() {
try{
runOnUiThread(new Runnable() {
public void run() {
//stuff that updates ui
queryAllRawContacts();
progressDialog.dismiss();
}
});
registerForContextMenu(contactListView);
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
// dismiss the progress dialog
}
};
t.start();
}
this is onCreate method of my activity class.
This activity actually one tab of a tabwidget. So when I click this tab and run the activity, it waits about 2 seconds and then show progress dialog like 10 millisec and updates the UI with the data. and dismiss progress dialog. What I would like to achieve is that as soon as the tab is clicked, the progress dialog will be shown and it takes about 2-3 seconds to load data. after loading and updating the UI the progress bar will be dismissed.
Thanks
queryAllRawContacts() needs to not be run on the UI thread. Change your code to the following:
Thread t = new Thread() {
public void run() {
queryAllRawContacts();
try{
runOnUiThread(new Runnable() {
public void run() {
//stuff that updates ui
progressDialog.dismiss();
}
});
registerForContextMenu(contactListView);
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
// dismiss the progress dialog
}
};
t.start();