I made this app that works fine, but when i leave the app and open it again it always force closes. how can i make it so when the user presses the home and or back key it will kill the app process?
Making it so when the app is opened again it has a fresh start.
You are not supposed to "kill the process". You should handle home button presses and other such interactions that navigate away from your app via the onPause() and onResume() methods.
In your onPause() method, you should save the state of your app. This can range from saved it in Bundles, SharedPreferences, sqlite or whatever form of persistence is appropriate for your app.
In your onResume() method, you should restore the state of your app so that the user is given an illusion that nothing has changed at all.
This is how android handles multitasking and this is how you must accommodate it within your app as well to efficiently and reliable suit your app to the android framework.
I suggest you go through the activity life cycles guide here first:
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
More on pausing and resuming an activity specifically here:
http://developer.android.com/training/basics/activity-lifecycle/pausing.html
Also, you might want to read up on data storage options here:
http://developer.android.com/guide/topics/data/data-storage.html
Related
My app uses a DefaultHttpClient to make network requests. On occasion (usually after resuming the app after a long period of time) the app will stop loading data and I need to clear it from the recent apps list before it loads content again.
My question is, what's the difference between:
- Closing an app by tapping the back button
- Clearing the app from the recent app list
When my app stops loading content, exiting via the back button and reopening does not fix the problem. Only killing the app by clearing it from the recent app list works.
Is there a way to "kill" the app when a user exits with the back button?
Thanks
Closing an app by tapping the back button
Pressing the BACK button, by default, destroys whatever the foreground activity is, returning control to the previous activity (or the home screen if there is no previous activity). It does not "close" an app.
Clearing the app from the recent app list
Usually, this will terminate the app's process. Contrast that with pressing BACK to destroy all of your activities, where the process remains running (at least for a while).
Is there a way to "kill" the app when a user exits with the back button?
Not really. You are better served fixing the bugs in your app.
usually after resuming the app after a long period of time
If "a long period of time" is less than 30 minutes or so, your process may have been terminated while your app was in the background, but Android will try to return the user to wherever the user had been in your app. This involves forking a fresh process for you and recreating your last activity. Sometimes, developers make assumptions that their process always starts with the launcher activity, with bugs being uncovered when the process starts with some other activity.
Also note that the HttpClient implementation in the Android SDK was deprecated in API Level 22 and removed in API Level 23. Either use an independent packaging of HttpClient or use some other HTTP client API (HttpURLConnection, OkHttp, etc.).
when you press back button then onBackpress() calls and app exit by normal actitvy life cycle and you can override onBackpress() (such that some apps give message that press again to exit) and do anything programmatic such that save any data or clear shared preference etc and when you clear it recent list then OS kills the app ,free the resources and there is no guaranty that activity life cycle proceed correctly such that some times onDestroy() not call. so basicly back press is part of our app and application self close by finish() method on other hand clear recent list is part of OS which forcefully kills the app
https://developer.android.com/guide/components/tasks-and-back-stack.html
follow this offical android link for more details
Is there a way to "kill" the app when a user exits with the back
button?
For the sake of curiosity, there is. its System.exit(0). What will happen if you execute this? The VM stops further execution and program(Activity) will be exit/killed right away.
NEVER DO THIS! There is a good chance your app will loose some data if its doing something while you trigger System.exit(0).
Here's the situation:
I want to check if the device is rooted or not every time the app comes to foreground (either because they're launching the app through App Drawer or coming back to the app via Recent Apps list). This check is done during onResume(), and it's working well.
The problem is that the intention is to check for root only once when the app comes to foreground, not when user is currently using the app. Since onResume() is called when an Activity comes to foreground, this means the check is done multiple times even when it's not needed, which comes at performance cost.
I thought of using a static variable to lock it, locking just before I perform the check to ensure the check is only called once. This is fine and dandy, but the problem is when to do the unlock?
onPause() is called before another Activity comes to focus, which
would negate the lock. I tried to use isFinishing(), but if a user
presses the back button, the activity is destroyed, which resets the
root checking lock and renders it less desirable. EDIT: Also, the Activity is not finished if the user presses Home button, which means it's also not reliable enough
onStop() and onDestroy() are not guaranteed to be called, and
they're also called if the user presses back button.
Is there a way to call a function exactly once when the app moves to background, without restricted to the constraints of onPause() above? I searched through the Activity, Application, and BroadcastReceiver documentation but couldn't find any mention about such a thing
In the end, I decided to use a combination of onUserLeaveHint(), custom startActivity() and onBackPressed() to do it, with some private static and non-static variables
I used onUserLeaveHint() to detect when user is going back to Home
or to Recent apps list.
onBackPressed() is used to tell the app that it is used for
navigation, while another onBackPressed() override is written at the
app entry point to detect when user is using back button to go back
to Home (can't believe onUserLeaveHint() doesn't account for that)
the custom startActivity() makes sure that onUserLeaveHint() is not
called when another activity is started. While onUserLeaveHint() has issues with forced interruptions (such as user receiving a call), it is deemed acceptable for now.
I did some research and found this blog but it makes use of onStop(), which is not guaranteed to run
Thanks for all the responses. I understand the concern about my security approach, but the question is about detecting when the user is leaving the app
When the main activity is loaded I can set the logged user's state as online by updating a remote database row. If the user exits the app I must set the user state as offline.
If the app is exited using back button I have the onDestroy() method and in there I can set the user state as offline, but if I exit using Home button and I kill the app from settings onDistroy() isn't called.
Is there a way to know when the main activity is no longer on stack, so I can update the user's state?
onStop will be triggered when user clicks on back or home button. So handle your events in onStop.
public void onStop () {
//do your stuff here
super.onStop()
}
EDIT:
Also try
#Override
protected void onPause()
super.onPause();
}
Also you could have it check if the app is finishing with
if (this.isFinishing()){
//Insert your finishing code here
}
The home button doesn't call onDestroy as the activity is still on the Activity stack where as with the back button it is generally removed. When the ActivityManager decides to remove the activity from the stack, usually after a period of inactivity or when resources are required, onDestory will be called at which point your field will be reset.
I am not able to say definitively because I don't know all the information but it would seem that removing the users logged in state when you press home (in onStart as suggested by coder_For_Life22) might be bad, as if you returned to the activity the user would have to log in again, perhaps unnecessarily and the client side session management will become even more complex.
Your method of session management seems fairly questionable anyway unless you have some sort of server side session management where, for example if there was inactivity on the session the database field would be reset.
UPDATE
The only way I can think it might be possible is using the ActivityManager.getRunningTasks() or ActivityManager.getRunningAppProcesses() and checking if your app is among them. If you kill your app like you are suggesting then your app will not be among them and thus you know. It seems like a hugely complex solution if at all possible as you would need a separate background service running (which you could call getSystemService(ACTIVITY_SERVICE) on to get the ActivityManager) just so after you kill your app you still have something running which can check for this and perform the appropriate actions.
Killing your app this way neglects the activity life cycle and thus there isn't a hook in your activity where you can perform shut down calls.
It seems much more sensible to check for inactivity on the server side and reset the field this way, people don't often kill their apps like this and when they do they aren't likely to quickly hand the phone to someone else who would be able to access the information maliciously.
If the data requires such security then you should rethink your security model.
Is there a good way to check if an entire application (not an activity!) is closed by the user? I want to log the time a user spends using the application, so a simple activity onPause() ,onStop() or onDestroy() is not sufficient.
There are several ways an application can be closed, either the user pressing the home button, search button or simply leaving the application. Is there a unified (eg. simple) way to see if any of these things happened?
There are several ways an application can be closed, either the user pressing the home button, search button or simply leaving the application.
Neither of these actually closes the application. The activities will continue to run unless you explicitly call finish() or the system kills them when it runs out of resources.
Why is not sufficient to use onResume() and onPause()?
will overriding finalize() to the App class (that extends Application) help for this job ?
if not , maybe a reference inside this class to another class that has this method?
I recently launched my first iPhone app and it seems to have people in the Android community asking for it ... so I started developing w/ the SDK.
The first thing I noticed is that in my iPhone app I would store certain session wide variables in the appDelegate. As I don't have this structure in Android I'm curious how Android developers keep track of application state across the app (hopefully w/out a ton of singleton objects?)
If the singleton object approach is how most developers do this - how can I ensure the application starts at a clean state each time the user clicks the "home" button and re-clicks icon (is there something I can add to my manifest to ensure it doesn't support multitasking in this way?)
My app has a lot of session specific state and for the first iteration won't yet support multitasking :(
First, android app can consist of multiple Activities.
If you want to share state between Activities use Application class: How to declare global variables in Android?
If you only have one Activity, then you can save state there.
Beware: when activity is not Active (it's GUI not showing) it does not mean that it is killed. So if you use your app and then close it, open another app, then go back to you app, it might be still "alive" (kept in memory) and the state would be preserved.
The best way to handle this is to hook into Activity lifecycle. Then you can set/reset data at will.
If you want to close the app when the user hits the "home" key, you can call finish() into your onPause method.
See this link:
Killing android application on pause
I find Singletons to be the best way to retain application state in Android applications. You can listen for when the user leaves the application through the onPause() and onStop() methods of the currently focused Activity, and do whatever you want with your data at that point. It's not good practice to try to override the OS's lifecycle management of your application (e.g. trying to kill your process when Back is pressed). If you want the app's state to reset every time the user leaves the application (via pressing Home, or being interrupted with a phone call or notification or what have you), simply put all your session data in the Activity itself. When the user leaves it will be destroyed and recreated when the user returns.
There are obviously specifics that I don't know about your application, but once you get familiar with the lifecycle of each screen (Activity) and of the application, you'll be able to use the callbacks to manage your state however you see fit.
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle