Is there a generic way to determine if there is dialog currently shown ? Sure, i can keep track of all createDialog and dismissDialog invocations, but that's cumbersome.
thanks
I use this method:
protected void showDialogSafe(int id) {
if (!isFinishing()) {
showDialog(id);
}
}
Which I grabbed from here: http://daniel-codes.blogspot.com/2009/12/activities-and-dialogs.html
When dismissing them I just catch the IllegalArgumentException.
Falmarri, keeping track of the dialogs seems to be easier said than done when you have multiple threads running. I thought my code was perfect, but I get a bunch of crash reports when my app tries to dismiss dialogs that aren't shown or tries to display a dialog when the activity is finished.
Related
I am having one java class in that class as soon some one purchases our application then it will start downloading and progress dialog has to appear instead it goes to some other page and when i come out of the application and when i restart then it starts downloading.
Please Help me out from this mess...
Thank you
Check the condition for dialog, before showing.
Like this
if(pDialog!=null)
{
if(!pDialog.isShowing())
{
pDialog.show();
}
}
and also while removing the dialog in onPostexecute() check for null.
if Still not works just remove the pDialog and try once with your code.
Two causes for your error happen:
The error will happen if you're trying to show a Dialog after you've exited an Activity.
Also, if an unhandled Exception was thrown in your AsyncTask, which would cause the Activity to shutdown, then an open progress dialog will cause the Exception.
According to the Log you've posted, the error happens after you call pDialog.show() which might be the 1st cause I've mentioned before.
Also you are calling finish() in many parts of your code, maybe one of these calls are making your Activity to stop and leaking your Dialog.
You must check which one of them is finishing your Activity before you show the Dialog. A good solution is to dismiss the Dialog (if it's showing) before calling finish().
I am using Robotium to automate testing of an application. Is there a way I can display an alert box while executing a particular test case.
Thanks.
It is possible to do, nearly everything is possible but before I give you the answer do you have a good reason to do this? I cant easily thing of a good reason why a test should open an alert box but you may know best.
Robotium has the method.
solo.getCurrentActivity();
Using this you can get an Activity Context and with such a thing you can do pretty much anything that you could do in an android activity. The page http://developer.android.com/guide/topics/ui/dialogs.html tells us how to make a dialog, you will notice the first line calls a method to get the currentActivity, instead of that I replaced it with the robotium method above.
// 1. Instantiate an AlertDialog.Builder with its constructor
AlertDialog.Builder builder = new AlertDialog.Builder(solo.getCurrentActivity());
// 2. Chain together various setter methods to set the dialog characteristics
builder.setMessage(R.string.dialog_message)
.setTitle(R.string.dialog_title);
// 3. Get the AlertDialog from create()
AlertDialog dialog = builder.create();
this will create a dialog, then just call the dialogs .show() method to show it on the screen.
Robotium tests do not run on the UI Thread, so any code in a test method will in the best case just not work and in the worst case throw and error and cause your test to fail.
To interact with the UI from inside a test method you need to run your code on the UI Thread. This can be done by writing that code inside a Runnable, and sending that Runnable to the runOnUiThread() method of the current Activity. Robotium's solo class has the getCurrentActivity() method, which will allow this execution. Here's an example of how you'd show a Toast using this technique.
public void testDisplayToastInActivity() throws Exception
{
Runnable runnable = new Runnable
{
#Override
public void run()
{
Toast.makeText(solo.getCurrentActivity(), "Hello World", Toast.LENGTH_LONG).show();
}
}
solo.getCurrentActivity().runOnUiThread(runnable);
}
You can use runOnUiThread() to perform many other actions that interact with your Activity, such as creating Alert Dialogs, if you want something more than a Toast. However, I'd suggest against doing any of this, even though you can. Robotium and other testing frameworks are meant to judge the correctness of your application code's execution, and should not inject any logic or UI modifying behavior beyond interacting with your application the way a user would. Your tests will be cleaner if you take any outpu from your tests and log them to Logcat or a file.
I have thought out an IMHO neat way of handling checked Exceptions, like so:
protected void handleException(Throwable e, int messageResourceId, ExceptionReaction reaction) {...}
which would be part of the app's BaseActivity (thus usable in all Activities).
Within this method I intend to show a dialog with the given message string and an OK button, and afterwards do something to react individually to the Exception (restart the activity, log the user out, reset database,...).
However, the dialog is started on the UI thread non-blockingly, and the Activities having called handleException(...) would just continue execution while the dialog is shown - which sucks, because something most probably has gone very wrong and e.g. an activity-restart might be needed.
Note that the UI thread can't be put to sleep or wait, since then the OK button in the dialog would not work at all.
Has anybody got an idea how to achieve this?
Has anybody got an idea how to achieve this?
Put your "do something to react individually to the Exception" in the dialog close-button handler, such as via a final Runnable.
Have you tried UncaughtExceptionHandler?
Refer this doc Thread.UncaughtExceptionHandler
Implement this interface and do the handling stuff in the callback uncaughtException(Thread thread, Throwable ex)
I have a problem that causes me some problems when a user (or another app, like the phone-application) pushes my application to the background.
My application does following:
A User can enter some information that is supposed to be pushed to a server.
When the user clicks "Send" i open a managed ProgressDialog and start an AsyncTask that performs the server communication.
When server communication is complete the AsyncTask reports back to my Activity where i perform a dismissDialog().
Directly after dismissDialog(), I will show another managed dialog using showDialog() that will inform the user about whether the submission was ok or if it failed.
This all works perfectly without any issues; however, when a call happens to come while the AsyncTask is running I get (seemingly random) one of these results:
The activity holding the managed dialog is dismissed completely and the previous view from the stack is presented when I come back.
The activity holding the managed dialog is still on screen, but it is grayed out without showing a dialog. The only way to fix this is to rotate the phone at which point it shows the "Submission sent"-dialog exactly the way it should and everything is ok after that.
All this happens without any warning messages so I get absolutely no clues as to why Android is behaving this way.
I know a way around this and that is to cancel the AsyncTask (so no dialogs are shown at the end). However, in this very use-case the requirements are that the app has to try to complete the server transaction so that there is as little confusion as possible (i.e. the user wondering if it was really sent or not).
Has anybody else had this issue and knows a way around?
I see recommendations to hold a reference to the asynch task in onRetainNonConfigurationInstance
What to do with AsyncTask in onPause()?
Or implement a bus:
https://github.com/commonsguy/cwac-bus/tree
EDIT: The complexity of your challenge is two fold:
1) saving and restoring state of your app on a kill such as when there is an incoming phone call
https://sites.google.com/site/jalcomputing/home/mac-osx-android-programming-tutorial/saving-instance-state
2) somehow continuing the asyncTask on kill instead of canceling it onPause
https://sites.google.com/site/jalcomputing/home/mac-osx-android-programming-tutorial/asynch
Both of these are significant challenges alone, and trying to fix both at the same time would give me a headache. In fact, I am getting a headache just thinking on it :) One clue is that you say the dialog returns on orientation change. This MAY be due to the fact that using the standard architecture for dialogs, the OS handles saving and restoring the state of dialogs for you on orientation change.
[EDIT] See CommonsWare
#Override
public Object onRetainNonConfigurationInstance() {
task.detach();
return(task);
}
and
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
bar=(ProgressBar)findViewById(R.id.progress);
task=(RotationAwareTask)getLastNonConfigurationInstance();
if (task==null) {
task=new RotationAwareTask(this);
task.execute();
}
else {
task.attach(this);
updateProgress(task.getProgress());
if (task.getProgress()>=100) {
markAsDone();
}
}
}
where task is an instance of
static class RotationAwareTask extends AsyncTask<Void, Void, Void> {
I see no reason why this would not work for all types of soft kills, but on a hard kill, well, you get killed. Dead is dead :)
Without looking at your code it is slightly difficult to say what the problem is. However, here is something you could use to help get around the problem. You can override the onPause() method of your Activity.
This is taken directly from the Android Acitivy javadoc:
onPause() is where you deal with the user leaving your activity. Most importantly, any changes made by the user should at this point be committed (usually to the ContentProvider holding the data)
I've searched through Stackoverflow, looked at the examples in Android Developer, and some books and I'm just not getting it.
I'm trying to show an AlertDialog Box that interrupts the program flow. Most of the examples I've seen don't have code after the dialog box and I need my program to stop executing until the AlertDialog button is pressed. Seems as if the AlertDialog is created from another thread and I'm not sure how to retrieve that thread.
Program logic: If the parsing is bad the program will force close. I want to let the user know to restart the program and everything will work. (I'm dropping and recreating tables and they are repopulated when the program starts back up)
Here's some code:
if(database populated)
{
....code.....
if(parseok.contentEquals("Error"))
{
doForceClose();
}
displayDate = "Last: " + parseok; //I don't want the program to continue to here.
//Rest of code in the method. If I continue the program will Force Close
}
else
do something else
Here's the AlertDialog method:
private void doForceClose()
{
String themessage = "Because some of the parameters have changed in the yada yada";
AlertDialog.Builder ad = new AlertDialog.Builder (this);
ad.setTitle("Internal Error");
ad.setMessage(themessage);
ad.setPositiveButton("Sorry", new OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
finish();
return;
}
});
ad.create();
ad.show();
}
except ad doesn't show and the program continues to its force close.
Obviously I'm not getting something. Any ideas?
edit: I am in a Class that extends Activity
I'm trying to show an AlertDialog Box that interrupts the program flow.
That does not exist in Android and various other UI systems.
I need my program to stop executing until the AlertDialog button is pressed.
No, you don't. Event-driven programming has been in use for a couple of decades.
Program logic: If the parsing is bad the program will force close.
That's your code -- rewrite it to behave better.
I don't want the program to continue to here.
Then use an else, or a return, or something.
except ad doesn't show and the program continues to its force close.
Your dialog will not appear until the main application thread gets control again to process your request -- show() is asynchronous. You are crashing before then, most likely.
In short, your strategy for dealing with your parsing problem is fundamentally flawed.
The Commonsware response s correct. Let me try and say the same thing in different words.
An alert dialog does NOT interrupt the flow of control. It is just "left showing" when the program is waiting for input.
thus the sequence
showAlert("this is a message);
showGallery();
return;
this shows only momentarily.
A way out of this is to put the showGallery() function call inside the Positive response from the AlertDialog.
So to put it another way. If you want to interrupt the flow of your app with an AlertDialog (which is wisely pointed out is the wrong thing to want) then put the code you want executed after the dialog into the onClick callback of the AlertDialog.
OK, I had a similar situation. I was expecting a dialog to pop-up but it didn't. Instead, an exception occurred. The place where the exception occurred was positioned a couple of rows behind the place where I was expecting the dialog. I fixed this exception and then my dialog appeared.
It looks strange, and I think the dialog needs time to appear while the program just continues to run and then the program encounter the exception, chronological (but not programatically) before the dialog.
That's why I got dialog after I fixed the exception place.