I'm a totally Android newbie who's learing about intents. I'm working on a small application to stream youtube videos. My question is do I have to do anything especial when invoking an intent? what happens when the intent fails? I'm I responsible for handling exceptions? Do I have to do register the intent so I can invoke it? Thanks
when you are invoking an intent, it means you will deal with any of the provided components like Activity, Receiver, service ect . so the case where operation inside this component throws some exception, for example an activity throws a NPE , that should be handlelled withing that component itself or within activity for this example . even if you will handle it at the time of invocation , despite being unusual and not recommended approach , like this :
try
{
startActivity( . .);
}
catch
{
}
this will not going to handle exception, thrown from inside activity code .
so conclusion is that neither android OS nor you should handle it at the time of invocation, but handle them at specific places where possible that any exception can accrue .
Related
There are some peculiarities on android that i hate like a hell...
The issues around isFinishing() of activity are the worst.
I do understand some actions are not allowed after or during this process, but the only way we have to check it is by this method, and somethimes it isn't effective let me show a very simple example and please guide me in how to solve it with the best practices:
I want to add a fragment to my screen
if(!this.isFinishing() && getSupportFragmentManager().findFragmentByTag(VerifyIdentityDialog.CHALLENGE_DIALOG_TAG) == null)
try {
new VerifyIdentityDialog((ChallengeRequiredException) e, new DefaultVerifyIdentityListener())
.show(getSupportFragmentManager(), VerifyIdentityDialog.CHALLENGE_DIALOG_TAG);
} catch (Exception e1) {
Crashlytics.logException(e1);
}
This code is running only on MainThread it explicitly checks if the activity is finishing before try but still i get around 2% of users running into exception on it...
The exception is:
java.lang.IllegalStateException
Can not perform this action after onSaveInstanceState
[Avoid pasting long stack trace since it is a default android exception and the related code is mentioned above]
1- Before i added !this.isFinishing() in the if, the exception was way more frequent, but still didn't solve it 100%
2- according to Crashlytics 97% are on background when it hapens, so I THINK the code starts, the user goes to background then it simple crashes
the question is...
how is the proper way to solve it... i hate catching exception for predictable situations
You can directly check whether the FragmentManager has saved its state via isStateSaved() - you should only show() your dialog if the state is not saved.
Whenever I start the app I want to know if the app recovered from a crash. Can I store it in a flag ?
Do the crash and regular app exit scenario go through the same steps(lifecycle) in android ?
You can override your crash exception by using Thread.setDefaultUncaughtExceptionHandler. But do not forget, If you would not close your application it will freeze the screen by OS.
Example code :
//variable that inside the application class
private Thread.UncaughtExceptionHandler defaultUEH;
public void onCreate(){
super.onCreate();
defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
#Override
public void uncaughtException(Thread t, Throwable e) {
handleUncaughtException(t,e);
defaultUEH.uncaughtException(thread,e);
}
});
}
private void handleUncaughtException(Thread thread,Throwable e){
//do whatever you like!
}
NOTE : There is no way to understand how is your program is opened
You don't get this information at all from the Android SDK. There are two options you could try, first is would be to have extensive logging/tracking of the apps life-cycle. In all of your activities keep track of when you activities are started, resumed, paused, stopped, and destroyed. (Also handle special usecase of when the device is rotated and the activity will experience a tear-down and restart). From here you will have information of when an activity has been stopped and you check the last state in the onCreate, onStart, or onResume of you activities to make sure that you're expected life-cycles where hit. If not, then you more than likely experienced a crash. Also note, on older version of Android certain teardown life-cycle callbacks weren't guaranteed to be called.
Second option would be to try using Thread.setDefaultUncaughtExceptionHandler. I have never personally used it but it may help in the usecase where an uncaught exception occurs. You could log such an event and check that flag once, the app is resumed. I am not sure of all of the side effects of using this mechanism such as, will this override the default uncaught exception behavior and remove the default stack trace that gets printed out, which would be very very very bad.
There is no way for the app to know whether it started from a crash; this is indistinguishable from starting the application for the first time after booting. In both cases you will see the onCreate lifecycle event for your activity.
If your application crashes, it stops processing lifecycle events. So no, lifecycle events will not be processed in the same way.
If you want to know whether your application is crashing, perhaps a better approach is to directly record when the application crashes. There are tools like Errbit that help record this when the application is running on general users' devices.
Try to add Exception handling to the code to whatever is causing a crash.
try{
//code causing the crash
} catch (Exception e){
//code to set flags whenever an event causing crash occurs.
}
I have a heavy-duty init process that I would like to run in 2 different places, depending on how the application started.
The heavy-init runs in background with an AsyncTask.
The cases are:
if the application was started from a Widget (via Intent), I need to make the heavy init inside the Application.onCreate
in any other cases, I need to make the heavy init inside the Activity.onStart
In other words, I'd like to know if inside the Application.onCreate there's a way to retrieve the triggering Intent.
thanks
Fabio
As it is reffeered in this link : Android- How to check the type of Intent Filters Programmatically?
You can use the getAction() of your intent to know what type of intent launched the activity.
I have a pretty large android application, all works well, unless when i get out of my application (onpause?) and when i try to get into my (not closed) application later.
So when i open it to continue where i started it throws a nullpointer exception or an inflate exception.
So where should i implement what?
OnCreate: only inflate layout elements?
OnStart: Assign values to inflated elements?
OnResume: do the same as in OnStart?
OnPause: should i save the value of my intent?
For example, one activity is all based on a certain ID that it will give in it's intent. At on create, he looks for his intent, and then sets the value of the intent and uses that to make some calls.
When i start the application at some later point, will he call the OnCreate (if the application window is not in RAM anymore?)? and when he does will OnCreate still have the intent (with values in there) with which it was called with?
There is a lot of documentation and training about this on the Android Developer website
I read a lot about using Toast or Log and putting them into Thread.setDefaultUncaughtExceptionHandler(...).
But I just can't get ALL exceptions displayed.
Please tell me (or point me to a resource) where it is described how to to it.
With working examples, when possible.
Thank you.
My guess is: when certain things go wrong (some global exception which destroys the whole app), toasts can't be displayed anymore.
If you are just developing don't try to use Toasts to display exceptions just work with Log.e() and the other Log functions it will all get displayed in LogCat you won't loose any exceptions. If you want to notify the UI that an Exception happened do it with a BroadcastReciever. So you have the place where you catch the Exception that fires an Intent which contains the message as an extra and in your Activity you just have to
registerReceiver(receiver, new IntentFilter("SOME_STRING_IDENTIFYING_THE_INTENT"));
Make sure you unregister the Receiver in the Activities onPause method.
The BroadcastReciever has a onReceive method that you can use to fire of the Toast.