ProgressDialog not appearing - java

I have code that starts a ProgressDialog inside an AsyncTask, it looks like this:
class RetrieveApps extends AsyncTask<String, Void, List<ApplicationInfo>> {
PackageManager pm;
#Override
protected List<ApplicationInfo> doInBackground(String...params) {
dialog = ProgressDialog.show(Apps.this,
"Retreiving Application list",
"Retrieving list of installed applications", true);
pm = getPackageManager();
return pm.getInstalledApplications(PackageManager.GET_META_DATA);
}
#Override
protected void onPostExecute(List<ApplicationInfo> result) {
for(ApplicationInfo nfo : result){
Drawable icon = nfo.loadIcon(pm);
String name = nfo.loadLabel(pm).toString();
if(name != null && icon != null){
apps.add(new App(name, icon));
}
}
dialog.dismiss();
}
}
I'm getting a RuntimeException saying
Can't create handler inside thread that has not called Looper.prepare()
It points at the line where ProgressDialog.show() was called.

public class RetrieveApps extends AsyncTask<String, Void, List<ApplicationInfo>> {
PackageManager pm;
#Override
protected List<ApplicationInfo> doInBackground(String...params) {
pm = getPackageManager();
return pm.getInstalledApplications(PackageManager.GET_META_DATA);
}
#Override
protected void onPostExecute(List<ApplicationInfo> result) {
for(ApplicationInfo nfo : result){
Drawable icon = nfo.loadIcon(pm);
String name = nfo.loadLabel(pm).toString();
if(name != null && icon != null){
apps.add(new App(name, icon));
}
}
dialog.dismiss();
}
#Override
protected void onPreExecute(){
dialog = ProgressDialog.show(Apps.this,
"Retreiving Application list",
"Retrieving list of installed applications", true);
}
}
try the above class , i moved the dialog creation in the onPreExecute method which runs on UI thread
Remember onPreExecute , onPostExecute and onProgressUpdate methods run on UI thread
doInBackground method runs on non-UI thread

Your dialog creation is suppose to be on the UI thread so that I can post back progress to the dialog, implement onPreExecute() with your dialog creation code. To post progress call and implement onProgressUpdate (Progress... values).

Move this:
dialog = ProgressDialog.show(Apps.this,
"Retreiving Application list",
"Retrieving list of installed applications", true);
To the onPreExecute method.
onPreExecute (and onPostExecute, where you will cancel the dialog) happens on the UI thread and therefore can make UI changes.
doOnBackground works in a different thread and therefore can't make UI changes.

Related

Showing ProgressDialog only once in a recursive AsyncTask

In the Java code I have executed an AsyncTask class and with the returned result I have done a recursive call to itself in the onPostexecute method. Example:
MainActivity.java
public void button_clicked(){
UploadAsync send_data = new UploadAsync(MainActivity.this);
send_data.execute("send first data", user_data, file_path);
}
UploadAsync.java
#Override
protected String doInBackground(String... params) {
String task = params[0];
if(task.equals("send first data"){
String user_data = params[1];
String file_path = params[2];
//send in the user_data to a php file
}else if(task.equals("send file"){
String file_path = params[1];
//send the file_path to another php file
}
}
#Override
protected void onPreExecute() {
ProgressDialog pd = ProgressDialog.show(context, "Sending", "Please wait");
}
#Override
protected void onPostExecute(String result) {
if(result.equals("data sent"){
UploadAsync send_data = new UploadAsync(context);
send_data.execute("send file", file_path);
}else{
//show error
}
pd.dismiss();
}
The code above is only an example made. Now the thing is, implementing this example will run the progress dialog twice. I have tried many ways to only show the progress dialog once while the AsyncTask is sending the user data and the file path but I'm not succeeding. Is there any suggestions on how to implement this correctly?
Can't you call pd.dismiss() and dismiss ProgressDialog for the current UploadAsync before executing new UploadAsync?
In onPostExecute first, dismiss the dialog and then start new asynctask like this:
#Override
protected void onPostExecute(String result) {
pd.dismiss();
if(result.equals("data sent"){
UploadAsync send_data = new UploadAsync(context);
send_data.execute("send file", file_path);
}else{
//show error
}
}
I hope this will help you.
Let ProgressDialog as global data .
private ProgressDialog pd;
#Override
protected void onPreExecute() {
// show the ProgressDialog
if (pd == null) {
pd = ProgressDialog.show(context, "Sending", "Please wait");
}
}
#Override
protected void onPostExecute(String result) {
if (result.equals("data sent") {
UploadAsync send_data = new UploadAsync(context);
send_data.execute("send file", file_path);
}else{
//show error
}
// edited here ,make the ProgressDialog dismiss
if (pd.isShowing() && pd != null) {
pd.dismiss();
pd = null;
}
}
In that case use callback mechanism between the async task and the caller(here, MainActivity).
Implement as I explained below.
Define an interface with showProgressDiaglog() and
DismissProgressDialog() methods.
MainActivity implements this interface and implements the two
methods to show and dismiss progress dialog respectively.
Define setter method in your AsyncTask class and call this setter
method from the MainActivity by passing this(this refers to
MainActivity) after creating the AsyncTask instance and before
calling execute method. store the passed interface implementation in
the AsyncTask class as an instance variable.
Modify AsyncTask constructor to pass the task type instead of passing
in the execute method and store this task type in the AsyncTask as an
instance variable.
Now from within the AsyncTask constructor, in onPreExecute()
method, call showProgressDialog() method based on the task type.
and in onPostEecute() method call dismissProgressDialog()
depending on the task type.

ProgressDialogue is not dismissing or cancelling at all

I have shown one progress bar on API call like below :
// prepare for a progress bar dialog
progressBar = new ProgressDialog(context);
progressBar.setCancelable(false);
progressBar.setMessage(context.getResources().getString(R.string.please_wait));
progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
But when I cancel or dismiss the progress dialogue created above it has no effect.
progressBar.cancel();
progressBar.dismiss();
Above two calls are in success & failure callback methods :
#Override
public void success(RockAPI.CallResult result) {
progressBar.cancel();
progressBar.dismiss();
....
}
#Override
public void failure(RockAPI.CallResult result) {
progressBar.cancel();
progressBar.dismiss();
......
}
I debugged the application at both success & failure points these lines of code getting executed but still progress dialogue persists. I have checked all the code there is no other place from which this progress bar show() is getting called. Its the same progress dialogue but just not getting canceled.
create such alike functions and call whenever needed..
ProgressDialog progressDialog;
public void showPD(String message) {
if (progressDialog == null) {
progressDialog = new ProgressDialog(getContext());
//progressDialog.setProgressNumberFormat(null);
//progressDialog.setProgressPercentFormat(null);
//progressDialog.setIndeterminate(true);
//progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setMessage(message);
progressDialog.setCancelable(false);
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.show();
}
}
public void hidePD() {
if (progressDialog != null) {
progressDialog.dismiss();
progressDialog = null;
}
}
You are setting cancelable as false so dont call progressBar.cancel(). Skip that and directly call progressBar.dismiss(). It should work. If it doesnt we will dig deeper.
Use true instead of false in your setCancelable and it will work .
progressBar.setCancelable(true);

ProgressDialog not being displayed in Activity with custom View

I am developing an Android app which has 2 classes. Game, which extends Activity, and GameView, which extends View.
When the game is loaded, it sets the content view to GameView, which is just a drawing class that uses a canvas to display the game.
I am trying to create a ProgressDialog in the Game class which will show a spinner after a certain action has been done, as this takes a long time to complete. So far I have the following:
setContentView(R.layout.activity_game);
ProgressDialog pd = new ProgressDialog(this);
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.setMessage("Calculating hint");
pd.show();
AsyncTask<String[][], Void, SudokuSquare> nextSquareThread = new GetNextSquare().execute(puzzleNumbers);
next = nextSquareThread.get();
pd.dismiss();
setContentView(gameView);
And my AsyncTask class looks like this:
private class GetNextSquare extends AsyncTask<String[][], Void, SudokuSquare> {
private ProgressDialog dialog = new ProgressDialog(Game.this);
#Override
protected void onPreExecute() {
this.dialog.setMessage("Finding next number");
this.dialog.show();
}
#Override
protected SudokuSquare doInBackground(final String[][]... args) {
try {
SudokuAdvancedSolver solver = new SudokuSolver(args[0]);
return solver.getOneValue();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
#Override
protected void onPostExecute(final SudokuSquare result) {
if (dialog.isShowing()) {
dialog.dismiss();
}
}
}
At the moment I have two ProgressDialogs, one inside the AsyncTask and one outside. Which one is correct? Also, the spinner is not being displayed at all. What am I overlooking which is causing this to be the case?
only the one outside is correct. because you are trying the main thread (the UI thread of your activity) by another thread (your asychronic task). you should use a handler in place of this :
1/ you show the progress bar
2/ you load the game in a thread
3/ when the game is loaded you send a message to the handler which will stop the progress bar.
See this exemple . you should dismiss your dialog in the handler (when the handler receives the message from the thread) .
If you don't implement a listener on Asynctask, i could suggest you to dismiss your progress dialog onPostExecute
private ProgressDialog dialog;
public void setProgressDialog(ProgressDialog dialog){
this.dialog = dialog;
}
#Override
protected void onPostExecute(final SudokuSquare result) {
dialog.dismiss();
}
and before you executing Asynctask add this code
nextSquareThread.setProgressDialog(pd);

Cancelling AsyncTask in Android

I am using AsyncTask in my Android application.
Here is my task:
public class MyTask extends AsyncTask<String, String, Boolean> {
private ProgressDialog progressDialog;
private boolean isCancelled = false;
public MyTask(ProgressDialog progressDialog) {
this.progressDialog = progressDialog;
}
#Override
protected Boolean doInBackground(String... params) {
try {
if (!isCancelled()) {
isCancelled = false;
} else
isCancelled = true;
} catch (Exception e) {
isCancelled = true;
}
return isCancelled;
}
#Override
protected void onCancelled() {
super.onCancelled();
isCancelled = true;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
progressDialog.dismiss();
if (!isCancelled) {
// start an activity
}
}
}
I want to cancel this task when pressing device's back button and also cancel the ProgressDialog, but this task executes quickly. When the back button is pressed, the ProgressDialog is cancelled, but the task completes.
This AsyncTask is invoked from an activity like this:
ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading");
progressDialog.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
if (myTask!= null
&& myTask.getStatus() != AsyncTask.Status.FINISHED
&& !myTask.isCancelled()) {
myTask.cancel(true);
}
}
});
progressDialog.show();
myTask = new MyTask(progressDialog);
myTask.execute();
When logging, I found that the dialog is dismissed (invokes onDismissListener) after executing the condition of onPostExecute(). How can I cancel this task properly?
My intention is cancel the task with back button press whether the task completes or not. Is it possible to cancel an AsyncTask from its onPostExecute()?
Actually, your code looks right,
In ProgressDialog's OnCancel()
After invoking myTask.cancel(true); method, onCancelled(Object), instead of
onPostExecute(Object) will be invoked after doInBackground(Object[]).
Note:
If you call cancel(true), an interrupt will be sent to the background thread,
which may help interruptible tasks. Otherwise, you should simply make sure to check
isCancelled() regularly in your doInBackground() method.
You can see examples of this at http://code.google.com/p/shelves.
But I suggest you to not canceling AsyncTask and just maintain your boolean Flag only dismiss the dialog on back pressed and onPostExecute() of AsyncTask decide what to do with result using your boolean flag condition.

Show ProgressDialog, Retrieve Data, and WAIT FOR IT

I'm writing an app that at many points will attempt to retrieve account information from a website. I'd like to write a single function ("getAccount()") to do the following:
Show a ProgressDialog
Make the call to the website
Wait for a response
Clear the ProgressDialog
Return control to the calling function after the first four steps are done
I'm not having a problem with getting the data from the page; the problem I have is with the whole "show dialog / wait for completion / return control to the calling function" portion. Either the ProgressDialog doesn't show at all, or the function returns to the caller immediately after making the data request from the site, without giving it enough time to retrieve the data.
Any help would be most appreciated.
EDIT: I'm adding a bit of code below for what I have with AsyncTask. Notice that I have the line MsgBox("done") inside grabURL(); this is simply a Toast call. When I run this code, "done" pops up while the HTTP request is still being made. This MsgBox line only exists so I can see if grabURL is properly waiting for GrabURL to finish (which it isn't).
public void grabURL() {
new GrabURL().execute();
MsgBox("done");
}
private class GrabURL extends AsyncTask<String, Void, Void> {
private ProgressDialog Dialog = new ProgressDialog(MyContext);
protected void onPreExecute() {
Dialog.setTitle("Retrieving Account");
Dialog.setMessage("We're retrieving your account information. Please wait...");
Dialog.show();
}
protected Void doInBackground(String... urls) {
try {
// Get account info from the website
String resp = GetPage(ThePage); // I have this classed out elsewhere
// Some other code that massages the data
AccountRetrievalSuccess = true;
} catch (Exception e) {
AccountRetrievalSuccess = false;
}
return null;
}
protected void onPostExecute(Void unused) {
Dialog.dismiss();
}
}
The message box done appears because AsyncTask is using a separate thread(s) to run doInBackground. The call to execute does NOT block. You could move message box done to onPostExecute following the call to dismiss. Tip. You may want to call progress.cancel in onPause or you may get unwanted behaviour on orientation change. Finally, if you are retrieving info in doInBackground, consider returning the info in doInBackground. The info will be passed to onPostExecute. So if the info is object MyInfo consider:
private class GrabURL extends AsyncTask<String, Void, MyInfo> {
Can't say for sure without seeing some code but sounds like you are making a asynchronous call to the website when you want to make a synchronous call (which will block and wait for return data) to the website instead.
You want to use an AsyncTask, generate a non-user-cancellable ProgressDialog in the onPreExecute, do your work in doInBackground, and dismiss it in onPostExecute.
Something like this:
public class MyApp extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// blah blah blah
URL url;
try
{
url = new URL("http://example.com");
new MyTask().execute(url);
}
catch (MalformedURLException e)
{
}
}
protected void doSomeStuff()
{
// stuff to do after the asynctask is done
}
protected void throwAWobbly()
{
// stuff to do if you didn't get the data
}
// inner class to do the data getting off the UI thread,
// so android doesn't "not responding" kill you
private class MyTask extends AsyncTask<URL, Void, Boolean>
{
private ProgressDialog dialog;
private boolean gotData = false;
protected void onPreExecute()
{
// create a progress dialog
dialog = ProgressDialog.show(MyApp.this, "",
"Doing stuff. Please wait...", false, false);
}
protected Boolean doInBackground(URL... urls)
{
// get your data in here!
return gotData;
}
protected void onPostExecute(Boolean result)
{
// get rid of the progress dialog
dialog.dismiss();
if (true == result)
{
// got all data!
doSomeStuff();
}
else
{
// oops!
throwAWobbly();
}
}
}
}

Categories

Resources