I am searching for best practices for App restarting scenarios on low-end phones, in which during app switching it restarts App with white screen and goes back to last screen where the user was previously. My question is how to save all the essential data in order to overcome such scenarios.
in that case application having onLowMemory() method in Application class
for example :
class MyApplication extends Application {
#Override
public void onLowMemory() {
super.onLowMemory();
// you can save your important data here as it is trigger when your application going to kill as it don't have enough memory
}
}
please let me know if these not working for you.
Related
After reading all the answers for questions like "how can I know if my Android app is in the background/foreground" I am still unsure what to do while an interstitial is running?
The preferred answer is basically to track it yourself by manually tracking onPause and onResume or using the new lifecycle library from Google. This works well, however this assumes you control the code for all the activities, when an interstitial runs that isn't your own Activity so this method won't work for it.
Other answers involve calling ActivityManager.getRunningAppProcesses() or ActivityManager.getRunningTasks(). These are of course not recommend and shouldn't be used. I'm also guessing future policy changes might limit this.
So how can I know if my app is on the foreground even while showing an interstitial ad?
Since someone might ask why I need to know this. My app uses the WebView. The WebView has a nasty habit of letting Javascript continue to run even when onPause() is called on the WebView. The only way I have found of stopping it is to run webView.pauseTimers() but that method applies to all WebViews, not just the one you called it on. So if I call that on when my onPause() is called on my Activity right before an interstitial ad, then the interstitial ad will probably freeze and might even ANR.
If you have Application class ,you can use that class to track.
public class StarterApplication extends Application implements LifecycleObserver {
#OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onAppBackgrounded() {
//App in background ,do your background stuff
Log.d( "onAppBackgrounded: ","called");
}
#OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onAppForegrounded() {
// App in foreground,do your foreground stuff
Log.d("onAppForegrounded: ","called");
}
I am doing a lot of reading on this currently but thought it never hurts to ask a knowledgeable group of developers as well.
This is a popular issue and there seem to be a lot of different ways of handling it.
I have an Android application. It uses OpenGL so when it starts up does a fair amount of data loading both from disk and then in VRAM. When the screen is rotated as well as when the power button is pressed (to put the phone into sleep mode) I lose all data and the activity is killed.
I don't want this. The app takes about 7 seconds to boot up and load its data and it is really annoying if you just sleep your phone for a second then have to wait the app to load all again.
I am familiar with the app lifecycle as outlined by Google but having a hard time implementing a solution that works for my particular case.
Any suggestions? My overall goal is to preserve the following in memory when the phone sleeps are is rotated:
1. App memory on heap
2. App memory in VRAM
Thanks!
So far:
public class MainActivity
private FH_SurfaceView fGLSurfaceView;
#Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
}
#Override
public void onRestoreInstanceState(Bundle savedState)
{
super.onRestoreInstanceState(savedState);
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Check if the system supports OpenGL ES 2.0.
final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
final boolean supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000;
if (savedInstanceState != null) {
/* NEED TO DO SOMETHING HERE?? */
return;
}
else{
this.fGLSurfaceView = new FH_SurfaceView(this);
setContentView(fGLSurfaceView);
}
}
#Override
protected void onResume()
{
super.onResume();
}
#Override
protected void onPause()
{
super.onPause();
}
}
The problem is that your Activity is holding a large amount of data. When the phone sleeps, it will likely target it to be destroyed for a variety of reasons, primarily to make sure there's memory for other tasks, but also because it might eating up processing cycles and Android knows it is not visible. Hence your problem. This does not happen to all apps, only "heavy" ones.
There may be nothing that you can do about this, but here are some suggestions:
Analyze your data loading. It might be that some parts are computationally expensive and therefore they are slowing the process, while other parts are heavy on memory but light on processing. Then in onPause dump the heavy memory part to improve the odds that Android won't kill your app. You might be able to get a 1-2 second load time instead of your current 7.
Consider creating a Service where the data resides and then binding to it in order to access it. Android does not expect a Service to be visible, and you can signal processing to cease in the onPause or onStop of your Activity to prevent Android from killing the service. I realize this is "tricky" as your data is currently in a custom SurfaceView class - and storing display data not on the UI thread is a pain.
Also, you might put the data into the Application class for similar reasons. The benefit of this is that you do not need binders to access the data. The drawback is that Android is more likely to destroy this than a Service I think (but that's experience talking, not testing - so, educated guess?). Also, messing with the Application class should be done with caution.
If all else fails, then try to provide an entertaining transition that acknowledges the silliness of the situation. In other words, communicating that you are aware of an unpleasant situation to a user is far better than ignoring it and hoping they don't mind.
Is there any way to know your application is running ?
I want to run a piece of code when Android app is just closed. Any suggestion will be appreciated.
Just to answer my own question now after so much time. When user close the app, the process is terminated with no notice. onDestroy is not guaranteed to be called. only when you explicitly call finish().
I suggest you to make a custom application class and note store the visibility of application wether it is running in background or not.obviously if you don't close the application like this
How to close Android application?
have a look at this so that you don't close it from background and perform the visibility check like this.
public class MyApplication extends Application {
public static boolean isActivityVisible() {
return activityVisible;
}
public static void activityResumed() {
activityVisible = true;
}
public static void activityPaused() {
activityVisible = false;
}
private static boolean activityVisible;
}
and this is how you register you application class to the manifest file.
<application
android:name="your.app.package.MyApplication"
android:icon="#drawable/icon"
android:label="#string/app_name" >
and override these two methods like this.
#Override
protected void onResume() {
super.onResume();
MyApplication.activityResumed();
}
#Override
protected void onPause() {
super.onPause();
MyApplication.activityPaused();
}
now check this status and perform what you like if it is running in background.You can take help of Booleans to check if the application is not closed by other reasons.
In general, there's no such thing as closing applications in Android: the user just stops using the app. It's up to the programmer to make sure that the user does not mention process creation and termination.
Please note that Android may kill the application process when it lacks memory and restart the application later.
For example, one of old office-like apps had the following bug: the user wanted to insert a photo, the office application invoked the Camera app, and Android killed the office app. The office app was not ready for a restart and lost all document changes (which was the bug). Apparently, the buggy app ignored the bundle passed to onCreate().
So the process life cycle and the application life cycle are different things. The process restart is visible to the application: the static variables get reset to their initial values (most likely, null). So it is possible to have a non-null bundle and null static data structures.
One example of executing a piece of code when the process dies may be found below:
Android camera locked after force close .
The problem solved in that post was that Android by itself does not close the camera when the process dies. I cannot tell from your post whether or not your problem is similar to this one.
If you uses, in your Activity, an object derivated from the class: ViewModel, you can capture the event: onCleared(); which is called always, after onDestroy().
See: https://developer.android.com/topic/libraries/architecture/viewmodel
I'm working on my 1st Android app and wondering how to handle activation/deactivation/starting/stopping globally, not on Activity level.
This great article shows states transition for Activities:
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
Is there something similar for Application states?
For example at iOS and Windows Phone app there is clear app states separated from activities (views, controllers, whatever).
I'm asking because I want to perform certain operations only once per app loading/exiting not with every activity starting/stopping
The answer is There is Simply No Direct method to do this
rather than in Application Class you can catch these events
#Override
public void onLowMemory()
{
super.onLowMemory();
}
#Override
public void onTerminate()
{
super.onTerminate();
}
So you will have to handle it in all the Activities you will be having
the following methods
onResume()
onStart()
onRestart()
onPause()
onDestroy()
You will have to implement in all Activity to handle for all application
A suggesstion
You can have some Variable in Application class to save application state
say create a variable like
public static boolean isPaused;
and set it from all activity on state change
The question you're asking is applicable for iOS and Windows but not really for Android.
Android doesn't really have a concept of an application as an object, although there's an Application class. Instead, an app is a loose collection of Activities. There are many good reasons for this state of affairs; for example, it supports fast app switching and easy interaction between Activities of different apps.
The best way to coordinate your "app" so that one Activity doesn't try to do something that's already been done is to use SharedPreferences to store app state. Nearly every other way of doing it is less preferred. Even if the system kills off your entire app, SharedPreferences will maintain the current state. The Application object won't.
Also, Android is based on pausing and resuming. An Activity or activities are created, pause, and resume. They may be destroyed, but that's an extreme case. A corollary to this is that apps should not have an exit button; there's no need for one. I sometimes see apps that have one, but what they're really trying to do is shut down a background Service or process. The best way to do that is to have an affordance that says "Sleep" or similar.
Have all activities inherit from the same hierarchy and put whatever you want in OnCreate, OnPause, OnResume, OnStop, OnDestroy and call the super where applicable.
Example
Parent
IamTheParentActivity : Activity
protected void onCreate()
{
setApplicationState(ApplicationState.Running);
}
protected void onPause()
{
setApplicationState(ApplicationState.Paused);
}
private void setApplicationState(Enum ApplicationState)
{
//Some Application Level Variable
Application.State = ApplicationState
}
Children
IamTheChild : IamTheParentActivity
protected void override onCreate()
{
base.OnCreate;
do other stuff
}
In android,is there any callback that is called when system runs low on memory or out of memory occurs.
For eg: there are three applications A,B,C running.In C out of memory is thrown.How can the application A come to know that so that it can clear its resources ,so that the android system wont kill the application A.
You must extend the Application class, and override onLowMemory() method.
public class App extends Application {
#Override
public void onLowMemory() {
super.onLowMemory();
// handle lowmemory stuff
}
}
Besides onLowMemory() there are other methods.
Use WeakReference to keep your cache and Android will handle OOM gracefully. Also, you can use a Service, which has higher priority than activities and will be destroyed after them.
override onLow memory method and do the stuff that you needed.
#Override
public void onLowMemory() {
// clear the unwanted resources from memory
super.onLowMemory();
}
NOTE: There is no guarantee that this method will be invoked correctly.
This is called when the overall system is running low on memory, and would like actively running process to try to tighten their belt. While the exact point at which this will be called is not defined, generally it will happen around the time all background process have been killed, that is before reaching the point of killing processes hosting service and foreground UI that we would like to avoid killing.
From developer Docs Link