I am using an AsyncTask (which I am starting in my main activity) to load some data:
Context context = VehicleTabView.this;
ProgressDialog progressDialog = new ProgressDialog(context);
progressDialog.setMessage("Loading...");
new LoadingVehicles(context, progressDialog).execute(null, null, null);
Here is the AsyncClass:
package com.example.schedule_vehicles;
import com.example.utils.VehicleNames;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
// Showing a ProgressDialog once loading the list of vehicles is completed using an AsyncTask
public class LoadingVehicles extends AsyncTask<Void, Void, Void> {
Context context;
ProgressDialog progressDialog;
public LoadingVehicles(Context context, ProgressDialog progressDialog) {
this.context = context;
this.progressDialog = progressDialog;
}
#Override
protected void onPreExecute() {
progressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
new VehicleNames(context);
return null;
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
}
}
The problem that the ProgressDialog is not showing on the screen.
I type Log.d, to see if the program is going through all the phases - onPreExecute, doInBackground, onPostExecute, and it is going through all the phases and doing the job that I need. But the ProgressDialog is not showing. I read a lot of information about this thing and it seems that the PRE and POST execute are started by the main thread, which is blocked by the DOINBACKGROUND method, and this is the reason not to see the ProgressDialog. I tried to find some answer how this is solved - but no success.
If anyone faced this, please share your experience. THANKS a lot!
You're passing the ProgressDialog to the Task, just show() it before you start the AsyncTask, not from within the AsyncTask.
Your code looks good to me. You are correct about your understanding of Asynctask and your use of them also appears correct.
The only thing that I can think of is that you must make sure that you are calling execute() on the UI Thread as well. From the code posted I'm not able to tell what context you are in.
Make sure you can pass in "this" as a context. That will tell you if your on the UI thread or not.
ProgressDialog progressDialog = new ProgressDialog(this);
Try :
ProgressDialog progressDialog = new ProgressDialog([Activity Name].this);
Let me know if this solves the problem or I'll see in depth.
Maybe you are missing the context.
ProgressDialog progressDialog = new ProgressDialog(this);
Normally when creating a ProgressDialog, you use the static method ProgressDialog.show(context, title, message). This will create and show the message and give you back a reference to the dialog.
onPreExecute and onPostExecute are called on the main thread, and are not blocked by the doInBackground, which runs on another thread. onPreExecute is called before doInBackground and onPostExecute is called after.
Here's some example code:
public static class InitializeTask extends MyAsyncTask<String, String, Response<Object>> {
private Activity activity;
private ProgressDialog dialog;
public InitializeTask(Activity activity) {
this.activity = activity;
}
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(activity, null, "Initializing...");
}
#Override
protected void onPostExecute(Response<Object> result) {
if (dialog != null && dialog.isShowing())
dialog.dismiss();
}
#Override
protected Response<Object> doInBackground(String... params) {
}
#Override
protected void attach(Activity context) {
this.activity = context;
dialog = ProgressDialog.show(context, null, "Initialize...");
}
#Override
protected void detach() {
if (dialog.isShowing())
dialog.dismiss();
activity = null;
}
}
Attach and detach are my own methods for referencing a cross orientation changes.
Related
Found that weird bahaviour of ProgressDialog.
I show ProgressDialog in onClickListener of list before starting new Thread and dismiss it inside that Thread but after all work is done:
GlobalProgressDialog.show(getActivity());
new Thread(new Runnable() {
#Override
public void run() {
//...all other logic
GlobalProgressDialog.dismiss();
}
}).start();
and that GlobalProgressDialog i use to simplify calls:
public class GlobalProgressDialog{
private static ProgressDialog progressDialog;
public static void show(Activity activity){
progressDialog = new ProgressDialog(activity);
progressDialog.setMessage("Loading...");
progressDialog.show();
}
public static void dismiss(){
if (progressDialog != null) {
progressDialog.dismiss();
}
}
}
Dialog appears but NOT exactly after show() being called! I have debugged it and found out that there are 4 standard Android classes are being operated:
AdapterView.java
AbsListView.java
Handler.java
Looper.java
And only after Looper the ProgressDialog is being snown. Is it possible to trick this or fix? Or maybe there's some my fault in code? What could it be?
The problem is that delay between item click and show() is like 1 sec. So application freezes for 1 sec. And only then dialog appears and all work done takes 1-2 sec, sometimes even 0.5 sec. In such cases its not cool to look at frozen app and flashed for 0.5 sec progress dialog.
Thanks in advance.
You're doing too much work on the main thread. show() will show the dialog, but it will do so on the main thread. It does not block execution until it is dismissed. So something you're doing in your code after calling show() and which you are not showing us, is causing the delay in the appearance of the dialog.
Just to be clear again, this has nothing to do with the Thread you're starting and changing it to an AsyncTask won't fix it, although it might be a good idea to do that anyway if the pattern fits your use case.
You should use a AsyncTask here.
public class DialogAsync extends AsyncTask<Void, Void, Void> {
private Context context;
private ProgressDialog progressDialog;
public DialogAsync(Context context) {
this.context = context;
progressDialog = new ProgressDialog(context);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.setMessage("Loading...");
progressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// Perform your logic here
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
progressDialog.dismiss();
}
}
Usage:
DialogAsync globalProgessDialog = new DialogAsync(getActivity());
globalProgessDialog.execute();
So I'm relatively new to Android (and Java). I've made a class which has your usual AsyncTask with a ProgressDialog in a static method because I want to call it from multiple Activities.
public class SomeClass {
// Some other methods, etc.
public static void SomeFunction(final Context context, String FilePath) {
new AsyncTask<Void, Void, Void>() {
private ProgressDialog dialog;
protected void onPreExecute() {
dialog = ProgressDialog.show(context, "", "Loading...", true);
}
protected Void doInBackground(Void... unused) {
for (int i=0; i<15000; i++)
System.out.println("Gatorade me, Bitch: " + i);
return null;
}
protected void onPostExecute(Void unused) {
dialog.dismiss();
}
}.execute();
}
}
The problem is that the statement
dialog = ProgressDialog.show(context, "", "Loading...", true);
in the onPreExecute() section of the AsyncTask gives error. The code runs fine without it.
So what can I do to solve this issue without creating a new java class file for AsyncTask. I know that works but I just want to make one file for this entire class so I can use it in multiple programs.
Thanks for your help!
Check whether you are passing application context or activity context while calling the function.
With application context, you cannot show the Progress Bar. If thats the case, try passing activity context.
SomeFunction(ActivityName.this,"path");
Document doc = new Obtainer(context, uri).execute().get();
This code in the activity class renders the Obtainer(which extends AsyncTask) which gets the xml document from the url. This is the onPreExecute method:
protected void onPreExecute() {
super.onPreExecute();
System.out.println("Pre execute began");
exception = null;
dialog = new ProgressDialog(context);
dialog.setMessage("Loading started");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
System.out.println("Preexecute end");
dialog.show();
}
context is set in the Constructor:
public Obtainer(Context c, String addr) {
context = c;
address = addr;
}
During the runtime I can see in the console output both "Pre execute began" and "Preexecute end" but the progress dialog is not shown. What is the probleM?
Use this code, it works for me:
class Obtainer extends AsyncTask<Void, Void, Void> {
private ProgressDialog dialog;
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(App.this); // App - your main activity class
dialog.setMessage("Please, wait...");
dialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// ...
}
#Override
protected void onPostExecute(Void result) {
dialog.dismiss();
}
}
And in your main activity class method call
new Obtainer().execute();
What Context are you passing when you create your Obtainer (AsyncTask subclass)?
If you are using the Application context via getApplicationContext(), it can not be used to create a Dialog (or any View for that matter). You need to pass it a Context that can create Views.
"If you're in the habit of using your application context (from a call to getApplicationContext(), for example) in places where you need a Context to create views, it's only a matter of time until you find a case where things don't work quite like you would want or expect."
From: https://plus.google.com/107708120842840792570/posts/VTeRBsAeyTi
I have been searching for an answer for this for some time now. I have an async task that downloads the database needed for my app, while this is downloading my app cant do anything as all the data it references is in this file, i have the app waiting for the file to be downloaded but i am attempting to show a progress dialog so the user knows something is happening while they wait for this to happen.
my code is currently
public class fileDownloader extends AsyncTask<Void, Integer, SQLiteDatabase>
{
private File dbFile;
private ProgressDialog progressDialog;
private Context context;
private SQLiteDatabase database;
private SQLiteDatabase.CursorFactory factory;
public fileDownloader(Context c)
{
super();
context = c;
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
progressDialog = new ProgressDialog(this.context);
progressDialog.setMessage("Downloading Database...");
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(true);
progressDialog.show();
}
#Override
protected SQLiteDatabase doInBackground(Void... v)
{
....
}
#Override
protected void onPostExecute(SQLiteDatabase db1)
{
progressDialog.dismiss();
}
however nothing shows up i have also tried directly calling ProgressDialog.show in the pre execute and moving this to the calling activity with no luck.
please help!
the solution to this was to look at the calling class the UI thread was getting blocked therefor the dialog never showed up.
Hmm - how long does your doInBackground method run? Maybe your dialog is shown, but the time is just too fast for the dialog to show up...
Below code is working fine, I am using it:
private class DownloadHomeSectionData extends
AsyncTask<Void, Void, Boolean> {
ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(mainScreen);
progressDialog.setMessage(getResources()
.getString(R.string.loading));
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(true);
progressDialog.show();
}
#Override
protected Boolean doInBackground(Void... params) {
for (HomeButton homeBtn : appDesigner.getHomeButtons()) {
StorageManager.getInstance().downloadFileSyncronously(
homeBtn.getTab_logo_selected_image());
StorageManager.getInstance().downloadFileSyncronously(
homeBtn.getTab_logo_unselected_image());
}
return null;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
progressDialog.dismiss();
}
}
In your case, I think you may be passing wrong context to ProgressDialog.
I am developing an application which require accessing a website for
data, and will show that data on device. I wants to fetch data from
Internet in background and show ProgressDialog or ProgressBar on
device and when application receive response from server app will
dismiss the dialog or bar and will show data .
For this i am using AsyncTask -
code for AsyncTask is as follows--
ServerTask extends AsyncTask {
#Override
protected void onPreExecute() {
dialogAccessingServer = new ProgressDialog(ctx);
dialogAccessingServer.setMessage(shownOnProgressDialog);
dialogAccessingSpurstone.show();
}
#Override
protected ServerResponse doInBackground(String... urlArray) {
String urlString = urlArray[0];
HttpResponse serverResponseObject = null;
//finding HttpResponse
return serverResponseObject;
}//end of doInBackground
#Override
protected void onPostExecute(HttpResponse serverResponseObject){
dialogAccessingSpurstone.dismiss();
}
}
and calling this code as follows--
ServerTask serverTaskObject = new ServerTask();
serverTaskObject.execute();
HttpResponse response = serverTaskObject.get();
//performing operation on response
but ProgressDialog is not shown.(I guess the reason for it is the
thread is not complete and android invalidate only when thread has
completed).
My Questions --
1- If my guess is right ? If yes then how I should implement it?
2- If there is any other better way to do this?
thanks
Following is a template code that displays a ProgressDialog while a task is executing in background:
class GetTask extends AsyncTask<Object, Void, String>
{
Context mContext;
ProgressDialog mDialog = null;
GetPhotoFeedTask(Context context)
{
mContext = context;
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
mDialog = new ProgressDialog(mContext);
mDialog.setMessage("Please wait...");
mDialog.show();
}
#Override
protected String doInBackground(Object... params)
{
// do stuff in background : fetch response
}
#Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
setProgressBarIndeterminateVisibility(false);
// mDialog.dismiss();
}
}
and you invoke it from your activity using new GetTask(this).execute() statement;
Note: Note that while displaying a ProgressDialog if the user switches the Orientation or causes event that ensues one, the code might break. It is advised to use Managed Dialogs for such cases.
If there is some pending work on UI thread 'Progress dialog' will not appear, so dialog.show() should be the last line on UI thread and any further work should be done in onPostExecute() method.