I use asynctask quite often however this time it doesn't work!
I have a UI contains a viewpager and fragments. To populate the view, it takes about 3 secs. Now I want to show the ProgressDialog until it finishes by using AsyncTask. But the ProgressDialog is not showing!!!!
Anybody can tell me the solution? Thanks
onCreate(...){
setContentView(...)
new LoadUI(MyActivity.this).execute();
}
public class LoadUI extends AsyncTask<Void, Void, Void>{
ProgressDialog pd;
Context context;
public LoadUI(Context mContext) {
this.context = mContext;
pd = new ProgressDialog(mContext);
aViewPager = (ViewPager) findViewById(R.id.aPagerDay);
}
#Override
protected void onPreExecute() {
pd.show();
}
#Override
protected Void doInBackground(Void... params) {
//Create ViewPager
//Create pagerAdapter
return null;
}
#Override
protected void onPostExecute(Void result) {
if (pd.isShowing()) {
pd.dismiss();
}
super.onPostExecute(result);
}
}
You can try out two options:
Either use the AsyncTask's method get(long timeout, TimeUnit unit) like that:
task.get(1000, TimeUnit.MILLISECONDS);
This will make your main thread wait for the result of the AsyncTask at most 1000 milliseconds.
Alternatively you can show a progress dialog in the async task until it finishes. See this thread. Basically a progress dialog is shown while the async task runs and is hidden when it finishes.
You have even third option:" if Thread is sufficient for your needs you can just use its join method. However, if the task is taking a long while you will still need to show a progress dialog, otherwise you will get an exception because of the main thread being inactive for too long.
The problem is the GUI is not ready in onCreate(). And nothing will be shown if I try to show Dialog in this state. A solution is move the dialog to activity onStart():
#override
onStart(){
new LoadUI(MyActivity.this).execute();
}
Related
My onStart() event looks like this:
protected void onStart() {
super.onStart();
ShowProgressDialog();
Function1(); //this takes a lot of time to compute
HideProgressDialog();
Function2(); //this function uses the values calculated from Function1
}
But the ProgressDialog wont show.
PS: AsyncTask is not a good solution for my problem because Function2 needs the values calculated from Function1 and I really dont want to chain 4-5 AsyncTasks.
Write the following code onstart
pDialog = new ProgressDialog(this);
pDialog.setMax(5);
pDialog.setMessage("Loading...");
pDialog.setCancelable(true);
pDialog.show();
Seems the activity is not on top of the activtiy stack yet. As can be read in the documentation:
http://developer.android.com/reference/android/app/Activity.html
Also if you do have processing it can block the UI Thread. I would suggest to put it in A A-Sync task. In the asynctask the order is still top to bottom so no need to create multiply a-synctask.
Do this to show the dialog box:
private ProgressDialog inProgressDialog = new ProgressDialog(this);
inProgressDialog.setMessage("In progress...");
inProgressDialog.show();
and to stop dialog:
inProgressDialog.dismiss();
And I think in your case you can give call to function2 using Async task and pass it as params.
You need to run Function1 and Function2 in a background thread. The ProgressDialog will only show once all of OnStart() has finished. So, you need to thread the time consuming code to free up the UI, otherwise the progress dialog won't show.
This is always good practice in Android, if you run time consuming stuff on the main thread the operating system will pester the user with messages about the app being unresponsive.
Some pseudo code:
OnStart()
{
ShowProgressDialog();
StartTimeConsumingThread();
}
Then, in the time consuming thread:
TimeConsumingThread()
{
Function1();
Function2();
RunOnUiThread(
CloseProogressDialog();
)
}
I think for long time calculation it is better to use AsyncTask.
You can do something like this:
private class Task extends AsyncTask<Void, Void, Void> {
ProgressDialog pd;
#Override
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(MyActivity.this);
pd.show();
}
#Override
protected Void doInBackground(Void... params) {
Function1();
runOnUiThread(new Runnable() {
#Override
public void run() {
pd.dismiss();
}
});
Function2();
return null;
}
}
There's a "download" button in each listview item. While the button is clicked, it will start a worker thread to down files. And at the same time, the button changed to progressbar and showing the progress rate.
So please show me some proper ways.
Use an AsyncTask since it has special methods for communicating with the main (UI) thread despite being asynchronous.
Here is an example:
http://android-er.blogspot.com/2010/11/progressbar-running-in-asynctask.html
Something like this:
public class DownloadTask extends AsyncTask<Void, Void, Boolean> {
protected void onPreExecute() {
ProgressDialog() progress = new ProgressDialog(context);
progress.setMessage("Loading ...");
progress.show();
}
protected Boolean doInBackground(Void... arg0) {
// Do work
return true;
}
protected void onPostExecute(Boolean result) {
progress.dismiss();
}
}
This should be nested in your activity class and executed like this:
new DownloadTask().execute();
You will likely need to adjust the asynctask to fit your needs but this will get you started.
When a button is clicked I'm calling the async class in a function and I need to show progressDialog until it runs the displaylist function. But it shows up only after the function finished running and closes immediately. Please help me what am I doing wrong here.
public class FilterAsyncTask extends AsyncTask<Void, Void, Void> {
ProgressDialog dispProgress;
#Override
protected void onPreExecute()
{
dispProgress = ProgressDialog.show(Filter.this, "Please wait...",
"Loading...", true, true);
}
protected Void doInBackground(Void... params) {
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
MerchantsActivity.displayList();
dispProgress.cancel();
finish();
}
}
Your AsyncTask will complete immediately because you do exactly nothing in doInBackground()! That's where your long-running background non-UI code is supposed to go...
I would recommend you not to use the static ProgressDialog#show method. Rather donew ProgressDialog() and initialize it accordingly and finally call show(). I have never used the static method and do not know how it works, but I have used the other option. Furthermore the static method seems to have no available documentation.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
AsyncTask block UI threat and show progressbar with delay
I want to show a progressDialog while retrieving JSON from any server. So I had used AsyncTask as a solution (not sure any different way out).
Everything is fine, the ProgressDialog works properly until I call .get() method using AsyncTask instance. I suppose it's blocking UI somehow. Here is my AsyncTask:
public class myAsync extends AsyncTask<String, String, List> {
String message; // for dialog message
ProgressDialog progress;
Intent myIntent;
Context ctx;
public myAsync(String message, Context ctx) {
this.message = message;
this.ctx = ctx;
progress = new ProgressDialog(ctx);
}
#Override
protected void onPreExecute() {
progress.setMessage(message);
progress.setIndeterminate(true);
progress.setCancelable(false);
progress.show();
}
#Override
protected List doInBackground(String... params) {
//returns any list after the task
return anyList;
}
#Override
protected void onPostExecute(List result) {
if(progress.isShowing())
progress.dismiss();
}
}
And here is myActivity which is calls AsyncTask:
myAsync asyncTask = new myAsync("Loading...", this);
asyncTask.execute("Any string", "Other string");
asyncTask.get(); // If I comment out this line, ProgressDialog works
After execute, when I tried to log the result from doInBackground and onPostExecute both there is no problem. But if I want to get with .get() the result ProgressDialog is not shown or shown so little time (maybe 0.2 seconds)
What's the problem?
Yes, get() waits if necessary for the computation to complete, and then retrieves its result. This means, that you are blocking your UI thread, waiting for the result.
Solution: Don't call get
Usually, you will call a function (callback) in the postExecute.
Calling .get() changes your AsyncTask into an effective "SyncTask" as it causes the current thread (which would be the UI thread) to wait until the AsyncTask has finished its processing. Since you are now blocking the UI thread the call to the ProgressDialog's .show() method never gets a chance to allow the dialog to draw itself the screen.
Removing the call will allow it to run properly in the background.
If you need to do processing after the task has completed I suggest you either put it inside the onPostExecute method itself or use a callback to the Activity from onPostExecute.
If I understand your question correctly, you need to update the progress of your AsyncTask in a ProgressDialog and this isn't currently working. So a couple of things to note: I'm not sure what you're trying to achieve with .get() but I'll assume you want to display the progress.
I've modified your program below to update the UI thread with your AsyncTask's progress. Everytime you need to update the progress, update that prog variable in the doInBackground method.
public class myAsync extends AsyncTask<String, Integer, List> {
String message; // for dialog message
ProgressDialog progress;
Intent myIntent;
Context ctx;
public myAsync(String message, Context ctx) {
this.message = message;
this.ctx = ctx;
progress = new ProgressDialog(ctx);
}
#Override
protected void onPreExecute() {
// Runs on the UI thread
progress.setMessage(message);
progress.setIndeterminate(true);
progress.setCancelable(false);
progress.show();
}
#Override
protected List doInBackground(String... params) {
// Runs in the background thread
// publish your progress here!!
int prog = 5; // This number will represent your "progress"
publishProgress(prog);
return anyList;
}
protected void onProgressUpdate(Integer... progress) {
// Runs in the UI thread
// This method will fire (on the UI thread) EVERYTIME publishProgress
// is called.
Log.d(TAG, "Progress is: " +progress);
}
#Override
protected void onPostExecute(List result) {
// Runs in the UI thread
for (int i=0; i<result.size(); i++) {
Log.d(TAG, "List item: " + result.get(i));
}
if(progress.isShowing())
progress.dismiss();
}
}
Try using runOnUiThread like this:
runOnUiThread(new Runnable(){
public void run() {
dialog.show();
}});
Running something on a AsyncTask means that its running away from the UIthread so usually you cant run ui operations from inside Async methods without handlers and stuff which I usually stay away from. I also handle such a solution by creating a progressDialog as a variable in my class above my oncreate so its visible to the whole class. I then call the progressdialog right before my asynctask and then since its visible to the whole class I call .dissmiss() in the onPostExecute
I have developed an android application .In that application getting information from web and displayed in the screen.At the time of getting information i want to load a progress dialog to the screen after getting the information i want dismiss the dialog
Please any one help me how to do this with some sample code
Thanks in advance
You need to implement an AsyncTask.
Example:
class YourAsyncTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
//show your dialog here
progressDialog = ProgressDialog.show(this, "title", "message", true, false)
}
#Override
protected Void doInBackground(Void... params) {
//make your request here - it will run in a different thread
return null;
}
#Override
protected void onPostExecute(Void result) {
//hide your dialog here
progressDialog.dismiss();
}
}
Then you just have to call
new YourAsyncTask().execute();
You can read more about AsyncTask here: http://developer.android.com/reference/android/os/AsyncTask.html
The point is, you should use two different thread 1st is UI thread, 2nd is "loading data thread"
from the 2nd thread you are to post the process state to the 1st thread, for example: still working or 50% is done
use this to post data