So theoretically, if I had a webview that loaded multiple pages in one session AND in one activity, if I was unable to save the state of that activity like I normally would via Bundle onSavedInstanceState, is there a way to prompt the app to check for available ram usage/memory?
I'm looking at a way to maintain activity state with webviews using the "Do not keep activities" turned on via developer options. Basically, when the app launches a new activity from an activity with a webview, on return, the pages that the user progress would have vanished because this would be a new activity instance.
Like, I'm looking for a possibility to check available ram usage via code to prompt the app to quit should there not be enough memory to use.
Generally, this should happen as Android will take the least frequent activity on the stack and destroy that to make more ram space available, so this is more of a theoretical question than a practical one.
Actually, your theoretic exercise is pointless. If Android needs memory, it just kills off background processes. It does not selectively destroy Activitys within an application. The documentation alludes to this possibility, but in reality this is never done.
The developer option "Do not keep activities" is something that always breaks complex applications when it is turned on, and it is something that can be used for troubleshooting and testing certain behaviour, however it doesn't really mimic the actual behaviour of the Android framework and it breaks a lot of code. For example, try using startActivityForResult() with that option enabled and see for far you get!
Related
We have an application, with links to various screens and reports.
On a web browser we can navigate to different pages and the pages are added to a navigation history, but I don't have to think about the back stack. I just assume that if the history is taking too much memory, the browser would trim browsing history as needed - But it sounds like in Android we could see out of memory errors if the stack is too big?
What should I do to keep the memory footprint of the back stack reasonable but let people navigate around the application and maintain a history of their past several screens? Is there a setting I should be looking for? Or just a little code script I should be running?
I'd like to use whatever Android natively offers rather than trying to create something from scratch here...
Or am I thinking about the problem the wrong way?...
Don't bother yourself. If system needs more memory it will destroy background activities and recreates them again when user will return to them.
Documentation:
When the system stops one of your activities (such as when a new activity starts or the task moves to the background), the system might destroy that activity completely if it needs to recover system memory. When this happens, information about the activity state is lost. If this happens, the system still knows that the activity has a place in the back stack, but when the activity is brought to the top of the stack the system must recreate it (rather than resume it)
Before reading this, note that I'm not talking about capturing the screen.
Motivation
Many times, in order to test apps, we need to go over many activities (including a loading/splash screen) till we reach the one we've just updated in order to test it out.
I want to reduce this time , by capturing the exact state of the app (memory,preferences,activities stack,...) in order to go there again.
Another example : The QA team could show me in which case a bug occurs, without having to show me the whole process till they got there (since it might not be reproducible) and then I could run the app, and know exactly where the exception was thrown and go there directly via the DDMS's logs .
Another example: We work on a game, and the QA team have tested the game for hours and reached a certain stage, and would like to save the current state of the app in order to test it from this point and make multiple tests on it, instead of running the app from the beginning each time , wait for it to load and also finish all of the stages till they reach this stage.
I think there are other scenarios where such a thing could be useful.
The problem
Such a thing is probably possible in the VM world (for example virualBox) , and it's probably possible for android emulators (at least according to this post , but they also say it's "finicky" , not sure what that means in this context) , but not for devices.
The above example, though they might work, they work for the entire OS and not for a specific app, so even if I choose to use them, it takes a long time to use (plus I need to use an emulator which is usually much slower than any device) .
I'm pretty sure that the current API doesn't support such a thing (and it's probably a good thing, for security reasons).
The question
Is it possible to capture&load entire app state by using ROOT ? Maybe by being a system app too?
Maybe there is already an app for this task?
Since it's very usual that an application saves its whole state in SharedPreferences and persistence in DB, in most apps you can backup and restore data and state using adb backup and adb restore, respectively:
Backup:
adb backup -f app.ab com.company.app
Restore:
adb restore app.ab
PS: This feature was introduced in ICS, and it's not required to be root.
More information in this tutorial.
Does anyone know of a way to show another class without creating a new instance?
It seems a bit crazy from a memory management point of view that each time you want to display a different form / page you need to use StartActivity which then creates a new instances of the class instead of reusing instances previously created.
Thanks in advance
I guess from what has been said - there is no real way to do it which won't hinder the "Back" functionality of the OS?
I'm building an app which is linear except on each screen it has a home button which then makes it possible to countermand this functionality and end in a loop - is there anyway you know of to destroy all over views and reset back to the main class? (IE prevent a memory leak from becoming a problem but also not damaging OS functionality)
Consider it a "clear history" without restarting the app
Not sure if this would work for Android (coming from a MS/C# background), but conceptually one option is to iterate through open forms looking for one with a specific handle. Then, once you find it, simply call the method to show that form. This would depend on there being a Java equivalent to the Application.OpenForms property in .NET.
It seems a bit crazy from a memory management point of view that each time you want to display a different form / page you need to use StartActivity which then creates a new instances of the class instead of reusing instances previously created.
Tactically, you are welcome to add FLAG_REORDER_TO_FRONT to bring an existing activity back to the foreground, so long as you understand the ramifications from a navigation standpoint.
However, your question is rather curious. How are you accessing StackOverflow?
Clearly it's not via a Web browser. Web browsers use the exact mechanism that you feel is "crazy", rendering Web pages even if that Web page had been viewed previously. They have been doing so for over 15 years, and we've been doing OK by it.
The Android navigation model is designed to approximately mirror that of the Web:
Users click on things to move forward
Users click on a BACK button to move to the previous thing they were looking at
Users click on a HOME button when they want to switch to some other major thing to go look at
By "reusing instances previously created", you're circumventing that navigational model. For example, let's suppose your activity stack were A-B-C-D, and you call startActivity() with an Intent for B and FLAG_REORDER_TO_FRONT. Now, the activity stack is A-C-D-B. When the user presses BACK times, they no longer are on the B they were looking at originally, but are back at A. In a browser, this would be rather strange behavior.
There are other flags on Intent, or attributes on <activity> in the manifest, that offer "reusing instances previously created". However, they are not there "from a memory management point of view". They are there where the traditional Web BACK-heavy navigation pattern does not fit your needs.
Assuming you aren't screwing up anywhere, Android will destroy under-utilized activities, garbage collect that memory, and even return that memory to the OS.
Is it advisable to create your own Activity stack (which contains only the activity names rather then the complete activity as in the default stack) to improve the memory consumption of the application.
What im basically doing is maintaining a string stack containing the activity names and override the back button functionality to launch Intent with the stack top and finish the current activity. I also add a parameter to decide if the current activity should go into the stack or not (useful in certain situation). So basically I do a startActivity every time I have to launch a new activity and finish the current one so that there is nothing in the default stack and on back press also start the activity from my stack and finish the current activity.
Ques 1: Is it advisable to do it this way? What are the possible problems that could happen?
Ques 2: Can someone give me an idea of the memory usage of the default Android activity stack so that I can compare it with my own implementation?
Is it advisable to create your own Activity stack (which contains only the activity names rather then the complete activity as in the default stack) to improve the memory consumption of the application.
Generally no, no more than a Web app typically hacks into the browser to change the browser history and delete items out of the browser cache.
What are the possible problems that could happen?
You lose your state on every operation. Normally, the BACK button takes the user back to the previous activity, with its state intact. There's even a framework for maintaining this state (onSaveInstanceState()) if Android elects to close up an activity to free up memory.
You also force more garbage collection than is necessary, by finishing activities that the user is not yet done with and forcing their re-creation, which wastes CPU time and battery life.
I have some nagging concerns about the impacts of your strategy on configuration changes (e.g., rotation, dock), but I can't put my finger on any specifics.
Can someone give me an idea of the memory usage of the default Android activity stack so that I can compare it with my own implementation?
You are asking the wrong question. The question you should be asking is: What is the evidence that there is a problem in the first place?
It is entirely possible that there is something rather unusual about your application that makes your strategy a sound one (e.g., lots of memory-intensive bitmaps). However, in general, unless there is a demonstrable problem, things like what you are doing fall under the heading of "premature optimization". Even then, there may be better solutions to whatever the actual problem is...but you won't know that unless and until you determine there is, indeed, a problem.
I seem to be missing something obvious here, why would I want more than one activity per application in Android? Does somebody have some solid examples?
Suppose you are creating a game. You need to have at least two activities - a welcome screen, and the actual game screen. The third activity in this example might be a settings page of the game.
Another example.
Suppose you are developing an application and you need to pop up a dialog, i.e. asking user to set username and password (Standard login screen). You might choose to create and activity and apply a dialog theme to it.
Think about it as the form of desktop application. you don't put everything on one form do you? :)
Sorantis' answer is spot on. Here are other thoughts as well:
Most Web applications, even AJAX-y ones, don't try to have everything in one single page. Some do, and those tend to be the ones that are slow as molasses to load (Evernote, I'm looking at you), have code that looks like a heaping mound of spaghetti, etc. Android is no different.
Also, state management for a super-complex Activity will be nasty, causing you problems with screen rotations and supporting being kicked out of RAM because you screw up onSaveInstanceState(). Memory management in Android assumes lots of cheap activities, not fewer massive ones. Intelligently handling the BACK button requires gobs of your own logic. If you want multiple entry points (e.g., Launcher icon and a MIME type handler and something some other app can call with startActivityForResult() and a search results handler), doing that in one activity will be a nightmare. And so on.
One very basic thing that makes having multiple activities in your program desirable is the use of the back button. I have a form in app after the user clicks search he is presented with another activity showing the results of the search. If he wants to change the search parameters he just can press back and without me doing anything particular he gets back to the search form. Doing this with one activity would be a lot of work for you.
The next thing is the memory management. Android will trigger the garbage collection automaticaly after changing activities that means my whole search form leaves the memory and doesn't take any resources away from the user.