I don't want my Activity to be re-created every time the device is rotated, so I've put the android:configChanges="keyboardHidden|orientation" tags in my manifest file.
Is there any disadvantage to this approach? The screen seems to re-layout automatically upon rotation, and everything works well, with the advantage that i don't need to re-initialize all the objects in my activity every time the screen rotates.
Thanks!
Not sure if you still want an answer, but I'm guessing the disadvantage is that it doesn't really let you know your applications works correctly if, say, the user answers the phone and puts your app in the background. In other words, if your app can survive orientation change with minimum difference in state, then it should be able to handle a dialer taking focus away.
Additionally, if you have any changes in resources depending on orientation or keyword (for example, if you have a dashboard screen and you want to change the position of your home buttons), Android won't automatically load those for you.
Looking at Google's design patterns, it seems Google uses both approaches. In the new Google+ app, for instance, they are not relying on the configChanges option because LogCat shows the unexpected resume of activity message, which for me shows only when an activity is destroyed and re-created. Google does use the option in other places, such as the Calendar application to edit appointments, and the Browser I think.
So it'd be a good idea to design your application without configChanges and add it later once everything works if there are some things that are inviable to restore (like whether the context menu is showing).
Related
On calling back my first activity ,it should call onResume.It is calling the same in android version 2.2.But when I checked in for android 4.1 it is calling onCreate method that calls splashscreen and hence it looks like the app is restarting.How could I make sure that onResume is called for every version of android?
Thanks
As Henry said, you can't guarantee that onCreate won't get called again - you're not in charge of that lifecycle. If the system decides to get rid of your activity while it isn't in the foreground, then when you return to it it will be recreated. If you want to make sure that you don't show the splash screen again you will need to save state to say that it has been shown (e.g. using onSaveInstanceState). As an aside, splash screens generally aren't a great idea on android, partly for this reason. It's better to view your app as a loose collection of activities that can be entered and reentered somewhat randomly, as the android system basically does. Where you see splash screens used on android, it's common to see them slightly misbehave.
If you want to keep track of your application lifecycle, to which a splash screen might correspond, then you can subclass the Application object and put a flag there. However, android may leave your app running for weeks, so the user won't necessarily see that splash screen very often.
Keep in mind that the true purpose of a splash screen is supposed to be to show the user something nice while a long loading process is happening, and not to put your branding in their face. If you use the approach with onSaveInstanceState (and often onRetainNonConfigurationInstance too) then the cases where you show the splash screen would indeed be those where you need to redo that loading process, so that would be correct. However, it's generally better to rethink the design and bring up a minimal UI quickly, then show that some data is loading.
Finally, here's someone who goes into great depth on this subject: http://android.cyrilmottier.com/?p=632
If the system has removed your activity while it was unused, it will receive an onCreate thats normal behavior.
You could make the splash screen part of a separate activity to avoid the problem.
To keep me busy during the holidays, I decided to learn about Android Development.
So I'm following the tutorial about an Activity's lifecycle. In the linked article, it says:
During normal app use, the foreground activity is sometimes obstructed
by other visual components that cause the activity to pause. For
example, when a semi-transparent activity opens (such as one in the
style of a dialog), the previous activity pauses. As long as the
activity is still partially visible but currently not the activity in
focus, it remains paused.
However, once the activity is fully-obstructed and not visible, it
stops (which is discussed in the next lesson).
I downloaded the sample app. The sample app has 3 activities, each with buttons that launches the other activity from an Intent. When I clicked "Start B", I expected that Activity A's state should be "Stopped" since it is now fully-obstructed with Activity B's layout. However, it was set to "Paused".
The only time that Activity A's state turns to Stopped is when I click "Start C" from Activity B's layout.
Why is this happening? Is it because of some optimization that is present on newer Android versions or am I misunderstanding the article?
Here's something I learned the hard way - Google's Android docs are not exactly accurate about everything!
Sometimes, The system optimizes certain behaviors which seem to deviate from the docs. The only way to know exactly how something works is by the hard way - by digging through the source!.
If your app depends on certain system level behaviors such as stopping and pausing to work exactly in a particular sequence as advertised then you will have a hard time. This behavior is controlled by the system and offers no guarantees.
The best way I have found to deal with this is to find out the contract that Google promises the developers and stick to it. For example, In this case, the contract says that if you follow the rules, implementing the required lifecycle callbacks when they are needed, then it will work, and you do not need to know exactly under what circumstances onStop(), onSaveInstanceState(), onPause(),onDestroy() etc are called.
In other words, If you do what is needed to be done when your app is paused by implementing onPause() , Then you don't need to know exactly when your activity will be paused. The pausing/resuming is controlled by the system and is subject to change from version to version (or maybe even from manufacturer to manufacturer if they choose to customize this behavior).
Wish someone had told me this when I had started. It would have saved me a lot of time and frustration. Hope this helps.
I need general advice.
I'm building an app that can be started via the icon (normal way) but also with an intent triggered by a click in the notification area (the app places an icon in the notification area). The is awaken when a time event / alarm occurs.
The app has 5 to 10 views. Is it better to open a new activity for each view? How can I be sure not to have mutliple tasks open? Say if my app is Activity-A, Activity-B, Activity-C and can be started from Activity-A and Activity-B (depending on if it's opened via the icon or the notification area) ... how do I clean everything upon app close?
Or is it better to have one activity and just switch views (xml layouts)?
I'll start of with what you should watch and read. It should be clear that navigation in Android is very easy to do wrong. Google has a history of doing differently from app to app, but they are getting better. This said, if you are to do an app you should know how it is intended to work, and the best way to do that is to read the docs. As mentioned, there was an excellent talk at IO'12. There is also a very good section on the design site, and finally there is a good section in the API Guides.
To summarize: a full screen is an activity (which in turn can be constructed of fragments). The activities should in virtually all cases be structured as a tree with the root being the activity that are launched from home. For every activity you should have an "up" activity that takes you up in the hierarchy. Note that this is different from back which should take you to the last full screen state you were in. Also note that full screen means that for example tabs should not be recorded in the "back history", since they provide navigation within a screen.
When it comes to tapping a notification it should be equivalent to: pressing home, remove the task from the recents view (clearing the task), opening the task, and finally take the shortest path to get to the activity presenting the info that the notification told you about. Complicated, yes indeed... But at least there is a helper class in JB and in the support library called TaskStackBuilder.
The key to all this is a UI design that follow the Android design guidelines. Take your time to make the design for your app, and make sure to separate up (static) and back (temporal).
It might be as simple as using a different launchmode, which you can define in the manifest or I think in the inent you are using. It takes some experimenting but SingleTask or SingleInstance may be the right choices for you,
Your activity should support onNewIntent in this case, to reuse existing Activities if that is the desired effect.
In this case I better use one activity or use fragments.
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.
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.