ProgressDialog doesn't appear when executing a Thread using AsyncTask - android

I am a newbie in Android programming so I hope you could help me. I have this AsyncTask which is executed through an OnClickListener event and inside the doInBackground() method, is the Thread which is not running on the UI Thread.
AsyncTask executed through OnClickListener:
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new MyAsyncTask().execute();
}
});
The AsyncTask which is a subclass of the MainActivity:
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
ProgressDialog progress;
#Override
protected void onPreExecute() {
// Show ProgressDialog before the task starts.
progress = new ProgressDialog(MainActivity.this);
progress.setMessage("Running...");
progress.setCancelable(false);
progress.show();
}
#Override
protected Void doInBackground(Void... params) {
// Since the thread is not running on the UI thread,
// I have to use the runOnUiThread() method so the
// app won't crash when the thread is complete.
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
new ThreadFromOtherClass(arg1, arg2);
} catch (Exception e) {
Log.e("Exception", "Something happened.", e);
}
}
});
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
// Hide the dialog when the task ends.
progress.dismiss();
}
}
I don't get any issues running the Thread but the ProgressDialog doesn't show during the task execute. However, if I exclude the runOnUiThread() method, the dialog appears but the app crashes when the Thread completes. Any idea what I'm doing wrong?

ProgressDialog doesn't appear
Create a constructor of MyAsyncTask and pass Context of MainActivty:
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
Context context;
public MyAsyncTask(Context context){
context.this = context;
}
ProgressDialog progress;
#Override
protected void onPreExecute() {
// Show ProgressDialog before the task starts.
progress = new ProgressDialog(context);
progress.setMessage("Running...");
progress.setCancelable(false);
progress.show();
}
Inside onClick:
new MyAsyncTask(MainActivity.this).execute();

Your code is working as it should. The problem there is that, you are actually starting another thread from inside doInBackground() method (which I really think is not a good idea for whatever reason it may be).
As soon as that second thread is started, you'll get a callback to onPostExecute(). Even though the "second" thread might have a lot of work to do, your MyAsyncTask is not waiting for it to finish.
So, actually, your dialog is shown and dismissed so fast, that you don't notice it in your screen.

Related

Displaying a ProgressDialog while waiting for a joined Thread

In my Activity, I load the content for a list from a DB, and want to display a ProgressDialog while it´s loading.
I got both working on it´s own, but if I load the data in a thread (which I should do?), the list is displayed before it´s data is loaded. But if I use join, the ProgressDialog doesnt even appear.
How can I combine this? Or is this not possible at all with threads? (AsyncTask maybe?)
Here´s the code for reference:
final ProgressDialog progressD=ProgressDialog.show(ShopSwitchActivity.this, "", "Loading..", true);
Thread myThread = new Thread(new Runnable() {
#Override
public void run() {
try
{
getData();
}catch(Exception e){}
}
});
myThread.start();
try {
myThread.join();
} catch (InterruptedException e) {
}
progressD.dismiss();
EDIT: Updated Code with AsyncTask:
public class LoadList extends AsyncTask<String, Void, Boolean> {
ProgressDialog dialog;
ShopSwitchActivity activity;
public LoadList(ShopSwitchActivity activity) {
this.activity = activity;
dialog = new ProgressDialog(activity);
}
protected void onPreExecute() {
this.dialog.setMessage("Loading...");
this.dialog.show();
}
#Override
protected void onPostExecute(final Boolean success) {
if (dialog.isShowing()) {
dialog.dismiss();
}
}
protected Boolean doInBackground(final String... args) {
try{
activity.getData();
} catch (Exception e) {
Log.e("error", e.getMessage());
}
return true;
}
}
Edit: My Solution
Using AsyncTask now to load the Data, and after it´s done, I refresh the list with the new data.
You can do it with AsyncTask. Write AsyncTask class in your main class that you want to do your operations. You can create the progress dialog in preexcecute of your async class and dismiss in onpostexecute of async class. Here is how you will do this:
class MyAsync extends AsyncTask<String, Void, Void> {
ProgressDialog pd;
Context co;
MyActivity ma;
public MyAsync (MyActivity ma){
this.ma= ma;
this.co = ma;
pd= new ProgressDialog(co);
}
#Override
protected void onPreExecute() {
this.pd.show();
super.onPreExecute();
}
#Override
protected Void doInBackground(String... params) {
// do your database operations here
return null;
}
#Override
protected void onPostExecute(Void result) {
// show db results and dismiss progress dialog pd.dismiss();
super.onPostExecute(result);
}
}
in MyActivity call as :
MyActivity ma = this;
new MyAsync(ma).execute();
You seem to miss the point of a thread. A thread occurs at the same time as your application. So your app doesn't call start then wait for the thread to be over- if it did you could just use a function. Instead your code continues to run. So if you just call join immediately, you're not doing anything. You'd get around a NetworkOnMainThreadException this way, but you'd still hold up the UI thread making your app totally non-responsive (and as a result not showing the dialog), and you'd eventually crash when a watchdog timer kills you.
Instead, the best way to handle this is to use an AsyncTask. Call getData in doInBackground(). Then dismiss the dialog in onPostExecute.
You should use AsyncTask instead actually.
Here is the link to the library. It is fairly simple:
1) onPreExecute() = show ProgressDialog
2) doInBackground() = execute your code
3) onPostExecute() = dismiss ProgressDialog
Here's a nice tutorial too.
In general:
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(this.context);
dialog.setMessage("Loading...");
dialog.setCanceledOnTouchOutside(false);
}
#Override
protected void onPostExecute(String result) {
if(dialog.isShowing()) {
dialog.dismiss();
}
}
private Thread myThread;
private ProgressDialog mProgDialog;
mProgDialog = ProgressDialog.show(ShopSwitchActivity.this,"","Laden..", true);
myThread= new Thread(new Runnable()
{
public void run()
{
myThread.setPriority(Thread.MIN_PRIORITY);
try
{
getData();
}catch(Exception e){}
runOnUiThread(new Runnable()
{
public void run()
{
if (mProgDialog != null&& mProgDialog.isShowing())
mProgDialog.dismiss();
} }
});
}
});
myThread.start();

ProgressDialog in a separate thread

I have a procedure that extracts data from a database and populates it to the list. I want to display progress dialog box while query is executed, but it visually appears only after the query is executed. I believe I have to run a ProgressDialog in a separate thread, but followed few suggestions and could not make it work.
So in my Activity I just have
private void DisplayAllproductListView(String SqlStatement) {
ProgressDialog dialog =
ProgressDialog.show(MyActivity.context, "Loading", "Please wait...", true);
//..................
//..................
//execute sql query here
dialog.dismiss();
}
thanks
1.show your process dialog in main thread
2.start a new thread (such as Thread A) to process your heavy job
3.when done, use handler to send a message from Thread A to main thread, the latter dismisses the process dialog
code like this
private ProcessDialog pd;
private void startDialog()
{
pd = ProgressDialog.show(MainActivity.this, "title", "loading");
//start a new thread to process job
new Thread(new Runnable() {
#Override
public void run() {
//heavy job here
//send message to main thread
handler.sendEmptyMessage(0);
}
}).start();
}
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
pd.dismiss();
}
};
Try something like this:
private class MyAwesomeAsyncTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog mProgress;
#Override
protected void onPreExecute() {
//Create progress dialog here and show it
}
#Override
protected Void doInBackground(Void... params) {
// Execute query here
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//update your listView adapter here
//Dismiss your dialog
}
}
To call it:
new MyAwesomeAsyncTask().execute();
All you need to do, is to tell Android to run it on the main UI thread. No need to create a Handler.
runOnUiThread(new Runnable() {
public void run() {
progressDialog.dismiss();
}
});

ProgressDialog while load Activity

I found this code in SO to show ProgressDialog while load Activity:
progDailog = ProgressDialog.show(MyActivity.this, "Process", "please wait....", true, true);
new Thread(new Runnable() {
public void run() {
// code for load activity
}).start();
Handler progressHandler = new Handler() {
public void handleMessage(Message msg1) {
progDailog.dismiss();
}
};
But I always get this exception:
java.lang.RuntimeException: Can't create handler inside thread that
has not called Looper.prepare()
I appreciate any help for this issue, thanks in advance.
Here is what I would do,
AsyncTask to do the "heavy work" in background:
public class MyTask extends AsyncTask<String, String, String> {
private Context context;
private ProgressDialog progressDialog;
public MyTask(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(context);
progressDialog.show();
}
#Override
protected String doInBackground(String... params) {
//Do your loading here
return "finish";
}
#Override
protected void onPostExecute(String result) {
progressDialog.dismiss();
//Start other Activity or do whatever you want
}
}
Start the AsyncTask:
MyTask myTask = new MyTask(this);
myTask.execute("parameter");
Of course you can change the generic types of the AsyncTask to match your problems.
The problem is because you are trying to create Handler inside a worker Thread. It is not possible. Create your Handler inside of onCreate() or somewhere else on the main UI. And you can send message to your handler from your Worker Thread.
This is because Android doesn't allow you to modify the UI from any other Thread other than the Main UI thread itself.
You need to create your handler on the main thread rather than inside OnClick.

ProgressDialog doesn't show up. Again

I'm confused because this has been working for me quite fine in other activities, and here I just basically copy-pasted the code, but ProgressDialog doesn't show up. Here's the code:
public class MyListActivity extends ListActivity {
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.mylayout);
final ProgressDialog progress = new ProgressDialog(this);
progress.setProgressStyle(STYLE_SPINNER);
progress.setIndeterminate(true);
progress.setMessage("Working...");
progress.show();
Thread thread = new Thread()
{
public void run()
{
//long operation populating the listactivity
progress.dismiss();
}
};
thread.run();
}
}
Not sure if this is the root cause of your problem, but try executing thread.start() instead of thread.run(). Executing start() will actually start a new thread and maybe give the progress dialog a chance to show.
You should use AsyncTask to manage the long operation.
private class LongOperation extends AsyncTask<HttpResponse, Integer, SomeReturnObject>
{
ProgressDialog pd;
long totalSize;
#Override
protected void onPreExecute()
{
pd = new ProgressDialog(this);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("Please wait...");
pd.setCancelable(false);
pd.show();
}
#Override
protected SomeReturnObject doInBackground(HttpResponse... arg0)
{
// Do long running operation here
}
#Override
protected void onProgressUpdate(Integer... progress)
{
// If you have a long running process that has a progress
pd.setProgress((int) (progress[0]));
}
#Override
protected void onPostExecute(SomeReturnObject o)
{
pd.dismiss();
}
}
From the above code, it's actually showing the dialog and closing it immediately in the Thread run() method. If you really want to see if it shows put a Thread.sleep(2000) to test, but yes what John Russell said is the way to go to use an AsyncTask instead.

How to display progress dialog before starting an activity in Android?

How do you display a progress dialog before starting an activity (i.e., while the activity is loading some data) in Android?
You should load data in an AsyncTask and update your interface when the data finishes loading.
You could even start a new activity in your AsyncTask's onPostExecute() method.
More specifically, you will need a new class that extends AsyncTask:
public class MyTask extends AsyncTask<Void, Void, Void> {
public MyTask(ProgressDialog progress) {
this.progress = progress;
}
public void onPreExecute() {
progress.show();
}
public void doInBackground(Void... unused) {
... do your loading here ...
}
public void onPostExecute(Void unused) {
progress.dismiss();
}
}
Then in your activity you would do:
ProgressDialog progress = new ProgressDialog(this);
progress.setMessage("Loading...");
new MyTask(progress).execute();
When you start a long-running process on Android, its always advisable to do it on another thread. You can then use the UI thread to display a progress dialog. You cannot display a progress dialog in the same (UI) thread in which the process is running.
Do the following to start your process
pd = ProgressDialog.show(this, "Synchronizing data", "Please wait...");
Thread t = new Thread(this);
t.start();
For this your activity should implement Runnable as follows
public class SyncDataActivity extends Activity implements Runnable
And finally a method to perform the long-running process
#Override
public void run() {
//your code here
}

Categories

Resources