What happens when we call the finish()method for the activity inside onCreate()?
Will the app get time to display the Activity, but then rapidly close, or won't it show anything?
This is just a doubt that I had before reading about some malware services for android that allegedly use this idea... Does it effectively work?
I just tested and debugged it, the Activity starts but is immediately closes once the event is generated.
As MrMins mention it will rapidly close. The lifecycle will skip over some important steps, therefore causing potential issues.
But to answer you question it will run only momentarily.
Here is the android documentation of the lifecycle: https://developer.android.com/guide/components/activities/activity-lifecycle.html
As per official documentation:
You can call finish() from within this function, in which case onDestroy() will be immediately called after onCreate(Bundle) without any of the rest of the activity lifecycle (onStart(), onResume(), onPause(), etc) executing.
Since
The visible lifetime of an activity happens between a call to onStart() until a corresponding call to onStop().
so the "visible lifetime" is not reached for that case.
Related
I'm a newbie Android developer. I know that when the screen orientation changes, the Activity is re-created and onCreate() is called again. What I couldn't find online, however, is how exactly the original Activity is destroyed. If some code called by onCreate() is in the middle of running, does that code just stop, or does the system wait for that code to finish before rotating the screen and calling onCreate() again? Thanks.
Activity's onCreate() is called everytime when the orientation changes and you should take care of your asynchronous task because the system does not wait, but you can avoid the re-creation of Activity by adding configChanges attribute of Activity in your AndroidManifest file in the activity tag.
android:configChanges="keyboardHidden|orientation"
According to the official documentation on configuration changes, once a device rotation is detected or the activity is started for the first time, onCreate() is called; you should assume that for all intents and purposes the onCreate() method will complete its execution before another screen rotation triggers activity recreation. Any code executed in your onCreate() should be done instantaneously since it shouldn't block your UI.
When rotating a screen we call it one of the Configuration Changes, it includes situations such as screen orientation, keyboard availability, and language changes. As quoted from Android official documentation here onDestroy() will be called then onCreate().
Some device configurations can change during runtime (such as screen orientation, keyboard availability, and language). When such a change occurs, Android restarts the running Activity (onDestroy() is called, followed by onCreate()).
But if there was any code executing on the main thread will have to finish (not other threads) and Android gives you time to save the activity data which you can receive on onCreate() when the activity is restarted. It does so by calling the method by calling the method onSaveInstanceState() as explained here in the documentation.
To properly handle a restart, it is important that your activity restores its previous state through the normal Activity lifecycle, in which Android calls onSaveInstanceState() before it destroys your activity so that you can save data about the application state. You can then restore the state during onCreate() or onRestoreInstanceState().
So the whole issues of code in the activity is that it will wait for the code to finish if it were executing on the main thread and if the code taking too slow it may make configuration changes very slow as it is discouraged in the documentation to make huge tasks in the main thread (for instance http requests).
This whole answer and descriptions and quotes has been taken from Android Official Documentation Guide, you can visit it for reference and more descriptions on configuration changes.
I understand when these methods are called: onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy().
However, will these methods actually do anything by default even if I didn't write any code in them?
For example, when the onPause method is called, will it automatically help me to pause and save resources even if I didn't specify the code for doing so? Or must I code everything manually?
If so, what is the general guideline of what kind of resources to save during OnPause and OnStop?
You MUST code those events if you want to do something inside your app. The activity lifeclycle (activity lifecycle part) will do tasks related to the android system, besides, the activity lifecycle give to you the opportunity to do things on your own when the events happens, but is up to you and your code to do things for your app.
If the only thing that you want to achieve is save/restore data you can use onSaveInstanceState. Take a look here How to use onSavedInstanceState example please
Refer to Activity Lifecycle
onCreate() Called when the activity is first created. This is where
you should do all of your normal static set up: create views, bind
data to lists, etc. This method also provides you with a Bundle
containing the activity's previously frozen state, if there was one.
Always followed by onStart().
onRestart() Called after your activity has been stopped, prior to it
being started again. Always followed by onStart()
onStart() Called when the activity is becoming visible to the user.
Followed by onResume() if the activity comes to the foreground, or onStop() if it becomes hidden.
onResume() Called when the activity will start interacting with the user. At this point your activity is at the top of the activity stack, with user input going to it.
Always followed by onPause().
onPause() Called when the system is about to start resuming a previous activity. This is typically used to commit unsaved changes to persistent data, stop animations and other things that may be consuming CPU, etc. Implementations of this method must be very quick because the next activity will not be resumed until this method returns.
Followed by either onResume() if the activity returns back to the front, or onStop() if it becomes invisible to the user.
onStop() Called when the activity is no longer visible to the user, because another activity has been resumed and is covering this one. This may happen either because a new activity is being started, an existing one is being brought in front of this one, or this one is being destroyed.
Followed by either onRestart() if this activity is coming back to interact with the user, or onDestroy() if this activity is going away.
onDestroy() The final call you receive before your activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.
How can this happen? I use a RecyclerView in an fragment and the fragment itself implements my click listener...
Sometimes, clicking an item in the list results in following error:
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
How can this happen? Clicks should be forwarded to their handlers synchronous and this should not happen, should it?
Some code fragment would really help. But your error already states Can not perform this action after onSaveInstanceState
This means that after the function onSaveInstanceState() has been called, you try to do something. Put that code before onSaveInstanceState() and you might have a solution.
OnSaveInstance is called when the activity is about to be destroyed.
The android gives a last attempt to save all the data in a bundle that can be retrived back when the activity is recreated onRestoreInstance.
Mostly this case occurs when the android decide to garbage collect your activity due to lack of memory.
The error state that you are doing some work on UI -fragment after the onSaveInstance has been called.
Android does not allow any work on fragments after this has been called and soon onDestroy will be called.
So kindly revisit your logic or place a isFinishing() check before doing any work.
Actually it's because you're activity is getting destroyed due to lack of memory and before it gets destroyed it saves the fragment state also, and like you mentioned it happens sometine, during this you might have clicked your own which tried calling that previous state non click on the destroyed fragment.
How can you avoid it
Use volley and Picasso. And check which part of your application is using more memory using memory monitor given in android studio.
Also if you are not able to reduce memory usage consider adding.
large heap="true"
in your manifest
Because an app I'm building will handle rather sensitive data I want to sync the SQLite db with the server every time the user logs in, and remove emty the db every time the app loses focus (because the user moves to the home screen or another app).
Seeing the Activity lifecycle, my idea was to do this by emptying the database in the onDestroy of every Activity. To test the described lifecycle I just Override all lifecycle methods (onCreate, onStart, onResume, onPause, onStop, and onDestroy), included some log messages in them, and fired up my app.
The log messages are included in my SettingsActivity. When I enter my app and move to the Settings it runs onCreate, onStart and onResume (as expected). When I then click a setting and move to the next screen it runs onPause and onStop (still as expected). To move back to the settings screen I click the back button and it runs onStart and onResume again (still as expected), when I now click the back button again to move back to the initial screen, it (to my surprise) runs onPause, onStop AND onDestroy.
So my questions;
Why does it destroy the Activity when the app is not finished?
And more importantly: how can I run my CleanUp method when the app closes or loses focus?
You can have some more information here : http://developer.android.com/training/basics/activity-lifecycle/stopping.html
Even if I think you already read it because you already study the activity lifecycle, you can see in the first figure that the onDestroy() is called after the onStop() and this call is totally managed by the system : you shouldn't expect any behavior. The system will decide itself WHEN to call this method, and sometimes, this method will never be called (see here : http://developer.android.com/reference/android/app/Activity.html). When system needs memory, your activity will pass in onStop() and nothing more.
So, to answer your second question, you shloud read the note in the documentation about the onDestroy() method :
Note: do not count on this method being called as a place for saving
data! For example, if an activity is editing data in a content
provider, those edits should be committed in either onPause() or
onSaveInstanceState(Bundle), not here. This method is usually
implemented to free resources like threads that are associated with an
activity, so that a destroyed activity does not leave such things
around while the rest of its application is still running. There are
situations where the system will simply kill the activity's hosting
process without calling this method (or any others) in it, so it
should not be used to do things that are intended to remain around
after the process goes away.
So it's pretty clear that it's a bad place to make your clean-up process. So you shloud use one of onPause() or onStop() method.
onStop() is described like this in the documentation :
Called when you are no longer visible to the user. You will next receive either onRestart(), onDestroy(), or nothing, depending on later user activity.
onPause() is described like this in the documentation :
Called as part of the activity lifecycle when an activity is going
into the background, but has not (yet) been killed.
[...]
When activity B is launched in front of activity A, this callback will be
invoked on A. B will not be created until A's onPause() returns, so be
sure to not do anything lengthy here.
[...]
In situations where the system needs more memory it may kill paused processes to reclaim resources.
We now know that onPause() is designed to allow you to save your data, and also that after onPause() was executed, the system could kill your process. So, making the clean-up in onPause() seems to be the safest place as you're pretty sure it will be called everytime.
Also, as you can read, making your clean up here can make your app slow, but anyway cleaning and recreating your database at each gain/loose of focus is a really heavy process...
To resume : make your clean up process in the onPause() method and your init process in the onResume(). Keep it mind that your application can be really slow with this kind of process.
Hope this can help you.
Destroying the Activity on back is the normal behavior. From the Android developers site
There are a few scenarios in which your activity is destroyed due to normal app behavior, such as when the user presses the Back button...
Has for detecting when the application goes to background, there is no simple method call that will let you know that. However this previous question contains some nice answers on how to do it.
You can't do this (call a function) in java part of app.
Only in the native part.
About your second question, this way you could run your CleanUp method when the app closes fully. You will need to implement your method inside a service that in this case I named "ExitService"
First create this service class:
public class ExitService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
System.out.println("onTaskRemoved called");
super.onTaskRemoved(rootIntent);
//do something you want before app closes.
ADD YOUR METHOD HERE, or CALL IT
//stop service
this.stopSelf();
}
}
Then, declare this way your service in the manifest "application" label:
<service
android:enabled="true"
android:name=".ExitService"
android:exported="false"
android:stopWithTask="false" />
Now, just start the service wherever you want to do something before your app closing.
Intent intent = new Intent(this, ExitService.class);
startService(intent);
I completed few android apps successfully but always I feel that I am not following the best practices of android developnment.
Few things which makes me feel developing a 100% complete android app is tough are
1. Making sure that my app is following all memory management stuffs
2.Making sure that my app is not going to crash
3.This one is always a big confusion for me-
I put all my code in oncreate() method including event listeners, phonestate listeners(If I require) etc..
What is the use of other methods like onResume(), onPause()... (I understood the concept of when they are called)
Should I stop all my event listeners in onPause() or by default android clears it?
Can I put all my event listener in onResume()?
Check dev Link
when ever over activity come in on stack again like previous it was not delete from stack then on resume is calling like if u want to see any list from any web service then after light off and again screen light is on then onresume() is call and u can call that webservices here and arrange list view with update values.
when ever your application go in pause mode then onpause() will call
you can follow above link i think your all query regards this will solve
The best reference for activity lifecycle callbacks is probably the the Android developers guide, and in particular this part:
http://developer.android.com/training/basics/activity-lifecycle/starting.html
Should I stop all my event listeners in onPause() or by default android clears it?
Either there or in onDestroy() but it depends what you're using them for; if you want the listener to listen even while that activity is paused or stopped then obv. stopping in onDestroy() is better.
Can I put all my event listener in onResume()?
It depends, onCreate() is only called once when your activity first starts up, whereas onResume() is called when your activity starts as well as every time your activity comes back from being paused or stopped. So if you stopped listening in onPause() then you probably want to start listening again in onResume(). If you stop listening in onDestroy() then you probably want to start listening in onCreate().