Why doesn't my Alert Dialog Work inside a Thread? - android

I'm using a thread so that I can show a progress dialog while my app loads some data. If there is an error it will stop the progress dialog and show the popup saying "error". However I found out that alert dialogs cannot run inside a UI thread and that I need to use a Handler. Can someone with help with this issue? Here is my code. Thanks
verifyCode.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
final ProgressDialog progressDialog = ProgressDialog.show(
Activate.this, "", "Loading...");
new Thread(new Runnable() {
public void run() {
try {
new AlertDialog.Builder(Activate.this)
.setTitle(getResources().getString(R.string.InvalidKey))
.setMessage(getResources().getString(
R.string.PleaseEntervalidRegistration)).setNeutralButton(
"OK", null).show();
progressDialog.dismiss();
//more code
}).start();
}

You can't make changes to UI element on non-UI threads. onClick will run on the UI thread, but since you spawn a Thread inside onClick then non-UI elements cannot be manipulated from inside that Thread. Move your AlertDialog and ProgressDialog calls to just prior to spawning the new Thread.
Also, as #lightblade suggested, If you need to do some sort of action which requires heavy background processing and UI manipulation based on that processing, then you should use AsyncTasks. It provides methods you can override for pre-processing, actual processing, post-processing, and updating progress.

Related

Progress Bar + Main Thread UI Update Wait for Thread to complete (Android Java)

I have been getting help to create a progress bar for my Android application. Lots of help here! I'm having an issue though that I am having a hard time fixing. I have a progress bar shown while the application attempts to download files from a networked computer. This works perfectly fine, however I need to update my UI incase an error occurs. I can't update the UI inside the thread and I want to update the UI from getRaceResultsHandler. Unfortunately it executes that code prior to the thread being completed. I have tried a few things with no luck. I have a code sample with my comments below if anyone can help.
public void getRaceResultsHandler (View view) {
dialog = new ProgressDialog(this);
dialog.setCancelable(true);
dialog.setMessage("Attempting to transfer race files. Please wait...");
// Set progress style to spinner
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
// display the progressbar
dialog.show();
// create a thread for downloading the files
Thread background = new Thread (new Runnable() {
public void run() {
//The Code here to execute the file download from the networked computer....
//Dismiss the progress bar because the download is either completed or failed...
dialog.dismiss();
}
});
// start the background thread
background.start();
//All Other Code Goes here to update the UI. Shows either an error message or a success based on the results of the download.
//My problem is that this code executes before the background thread is completed. I need it to wait until the thread is completed.
}
Try to dismiss that dialog using Handler
Handler h = new Handler(); // Create this object in UI Thread
Thread background = new Thread (new Runnable() {
public void run() {
h.post(new Runnable()
{
public void run()
{
dialog.dismiss();
}
};
});
You should use AsyncTask instead of normal Thread
AsyncTask<Void,Void,Void> aTask = new AsyncTask<Void,Void,Void>()
{
#Override
public void onPreExecute()
{
// Setup some UI Objects
}
#Override
public void onPostExecute(Void result)
{
dialog.dismiss();
}
#Override
protected Void doInBackground(Void...params)
{
// your download stuff
publishProgress(object) // <-- if you want to update the progress of your download task
}
});
Note: Didn't try my own, have no IDE here in my friend's laptop

Android: show a progress dialog then dismiss properly

I've found that a lot of people are having a similar problem but I am simply trying to show a dialog while I am grabbing some data off a URL and then dismiss properly after the data is retrieved. Here is what I'm trying to do (This is in my onClick() method for a refresh button):
dialog.show();
// do some work
dialog.dismiss();
Doing it this way you never really see the dialog at all. I've tried doing it using an extra thread such as:
Thread t = new Thread() {
public void run() {
dialog.show();
}
};
But this way I get an error and a force close down...
What is the best method to do this?
For the task you are trying to implement:
dialog.show();
// do some work
dialog.dismiss();
Now, to implement above, there is concept of AsyncTask, the best way to implement Threading task, as its also known as Painless Threading in Android.
AsyncTask has 4 main methods:
onPreExecute() - Here you can show ProgressDialog or ProgressBar.
doInBackground() - Here you can do/implement background task
onProgressUpdate() - Here you can update UI based on the intermediate result you receive from webservice call or from background task
onPostExecute() - Here you can dismiss dialog or make progress bar invisible. Also you can do the task which want to do after receiving result from background task or webservice call.
For this kind of task mostly I recommend you to use the AsyncTask. Here is one good example of it which will help you.
And for this question as You are making UI related task and for that please use the UI thread.
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
//Show or Hide your ProgressDialog
}
});
Try to use runOnUiThread of the Activity instead of using Thread.
Check the following code snippet.
runOnUiThread(new Runnable() {
public void run() {
dialog = new ProgressDialog(ctContext);
dialog.show();
}
}
});
I think this will help you.

Progress Bar on Android gets displayed after complete onClick() execution

I have a Button, and upon pressing it, the onClick() would process user's request. However, this takes a little time, so I would like to have a View showing "Please wait, processing..." immediately upon pressing this Button, while its OnClickListener does its thing.
My problem is, this "Please wait, processing..." which I placed at the very beginning of onClick(), only appears AFTER the whole onClick() is done. In other words, after the whole processing is done. So, I was wondering, how do I make a View saying "Please wait, processing..." before the actual processing has begun?
As #Blundell pointed you may process long-running operation on a separate thread to avoid freezing of UI thread. However in Android there's a better alternative for general-purpose Handler which is called AsyncTask. Please refer to this tutorial for details.
You can do this by just using AsyncTask without dealing anything else.
First create new AsyncTask class on "onPreExecute" change ui to show
that you are processing sth
Second do your all backend time consuming job on "doInBackground"
method (do not call any ui updating method from here)
Third change your ui to show that process is finished or whatever you
wanna do.
yourUiButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
new NewTask().execute();
}
});
class NewTask extends AsyncTask<String, Void, Task>{
#Override
protected void onPreExecute() {
super.onPreExecute();
//this part runs on ui thread
//show your "wait while processing" view
}
#Override
protected Task doInBackground(String... arg0) {
//do your processing job here
//this part is not running on ui thread
return task;
}
#Override
protected void onPostExecute(Task result) {
super.onPostExecute(result);
//this part runs on ui thread
//run after your long process finished
//do whatever you want here like updating ui components
}}
Do the processing on another thread so that the UI can show your dialog.
// Show dialog
// Start a new thread , either like this or with an ASyncTask
new Thread(){
public void run(){
// Do your thang
// inform the UI thread you've finished
handler.sendEmptyMessage();
}
}
When the processing is done you will need to callback to the UI thread to dismiss oyur dialog.
Handler handler = new Handler(){
public void handleMessage(int what){
// dismiss your dialog
}
};
AsyncTasks.
Place the displaying of the progress dialog in onPreExecute
Do your thing in doInBackground
Update whatever needs to be updated in the UI, and close the dialog in onPostExecute
You will need something like this
public void onClick(View v){
//show message "Please wait, processing..."
Thread temp = new Thread(){
#Override
public void run(){
//Do everything you need
}
};
temp.start();
}
or if you want it to run in the UIThread (since it is an intensive task, I don't recommend this)
public void onClick(View v){
//show message "Please wait, processing..."
Runnable action = new Runnable(){
#Override
public void run(){
//Do everything you need
}
};
v.post(action);
}
put ur code inside a thread and use a progress dialogue there...
void fn_longprocess() {
m_ProgressDialog = ProgressDialog.show(this, " Please wait", "..", true);
fn_thread = new Runnable() {
#Override
public void run() {
try {
// do your long process here
runOnUiThread(UI_Thread);//call your ui thread here
}catch (Exception e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(null, thread1
"thread1");
thread.start();
}
then close your dialogue in the UI thread...hope it helps..

Using progressDialog in android?

I am using this code to display a Progress Dialog which is working fine:
dialog = ProgressDialog.show(this, "Please wait",
"Gathering Information...", true);
Thread thread = new Thread()
{
#Override
public void run() {
if(Chapter_sync.size()>0){
storemodule();
c.open();
for(int i=0;i<Chapter_sync.size();i++)
{
downloadPDF(Chapter_sync.get(i));
System.out.println("SYNCED"+i);
c.update(Chapter_sync.get(i));
}
}dialog.dismiss();
}
};thread.start();
LinearLayout parentlayout=(LinearLayout)findViewById(R.id.chapterholder);
parentlayout.removeAllViews();
setUpViews();
}
}
Here what I am trying to do is display a Progress dialog till all computation is done.
As it completes i wanted to setup all views again. But the setUpViews() is called before the thread starts. I am not so good at thread basics .Could any one help me understand why is this happening and how can I get my own results?
The problem is you are not using handlers. Simply do this,
dialog = ProgressDialog.show(this, "Please wait",
"Gathering Information...", true);
Thread thread = new Thread()
{
#Override
public void run() {
if(Chapter_sync.size()>0){
storemodule();
c.open();
for(int i=0;i<Chapter_sync.size();i++)
{
downloadPDF(Chapter_sync.get(i));
System.out.println("SYNCED"+i);
c.update(Chapter_sync.get(i));
}
}dialog.dismiss();
}
handler.sendemptyMessage(0);
};thread.start();
And in your onCreate() create Handlers,
Handler handler=null;
handler=new Handler()
{
public void handleMessage(Message msg)
{
progressDialog.cancel();
if(msg.what==0)
{
LinearLayout parentlayout=(LinearLayout)findViewById(R.id.chapterholder);
parentlayout.removeAllViews();
setUpViews();
};
You can't update your UI from background thread. Either you have to use AsyncTask or to use handlers from your background thread to inform your main thread that the background action has been completed.
Thread scheduling is dependent on the operating system. So instantiating your thread does not ensure that your thread will run whenever you want.
The problem you are facing can be best handled using async task. Or if you have a callback that lets you know when your download is completed then you can dismiss the dialog on the callback. Make sure you dismiss it inside a UI thread by doing.
mActivity.runOnUiThread() or any other such methods.
In your code if u see
After Starting the Thread you have call your method setUpViews(), which does not wait for your thread to complete and setups your views.
Use Handler.post after the dialog is dismissed in your thread which gather your information.
handler.post(new Runnable()
{
setUpViews();
});
So after the your operations completed your setupViews will be called by your Handler.

Are progress/indeterminate dialog boxes added to the end of the UI thread? Do they require a second thread?

I have a simple dialog box. When I click a button the dialog box is supposed to be shown, while a file save operation is performed, and then the dialog box is dismissed. The problem I am having is the dialog box isn't shown until after the onClick event of the button finishes.
Taken from the Dialog developer doc:
The setup is simple. Most of the code
needed to create a progress dialog is
actually involved in the process that
updates it. You might find that it's
necessary to create a second thread in
your application for this work and
then report the progress back to the
Activity's UI thread with a Handler
object. If you're not familiar with
using additional threads with a
Handler, see the example Activity
below that uses a second thread to
increment a progress dialog managed by
the Activity.
Why isn't the dialog shown until after the onClick method finishes? Is the dialog added to the end of the UI thread?
Is the only way to do this to create a new thread and handler? That's fairly bad wording in the developer doc if so.
Thanks all.
Button send = (Button) findViewById(R.id.send);
send.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
showDialog(SAVING_DIALOG);
//Do all the file saving operations
...
...
dismissDialog(SAVING_DIALOG);
}
});
Here is the dialog
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case SAVING_DIALOG: {
ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("Saving file...");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
return dialog;
}
}
return null;
}
Shouldn't work be done on a thread when using the progress dialog?
http://www.helloandroid.com/tutorials/using-threads-and-progressdialog
For showing a progress dialog while something is processing, you have to process your code in another thread, otherwise your dialog freezes or wont be shown.
So I would use following method:
final Handler threadHandler = new Handler();
// in your onClick:
showDialog(SAVING_DIALOG);
new Thread(){
public void run(){
// new thread
// Do all the file saving operations
// ...
threadHandler.post(new Runnable(){public void run(){
// back in UI thread
dismissDialog(SAVING_DIALOG);
}});
}
}.start();

Categories

Resources