Well the question is that I have an app with multiple activities. The main activity runs several animations and the problem is that if I run the app and stay in the main activity everything is all right but if I go to another activity (the setting activity, for example) and come back to the main one, after some time the hole app begins to lag.
Any clue about why is this happenning? May the other activities keep running in background or something like that?
Thank you all.
As far as your scenario is concerned, try following
Set up proper navigation within your app.
If you keep closing and opening your activities (when your activity is still holding on resources), your memory usage keeps piling up. So make sure you release all resources like camera, or finish an animation before calling finish();
Try different android:launchMode options for your Main Activity /Home screen activity. (this depends on your app design)
In order to find who is calling your app to use more memory, try https://developer.android.com/studio/profile/investigate-ram.html
PS. You could've given more details like #Michiyo mentioned.
Related
When I press the 'Home Button' it will put the app in background (paused, as expected), then when I open the app again it will open with the Main Screen instead of the Previous Screen.
This also affects the 'Back Button' creating a stack of multiple Main Screen.
Any ideas?
I would highly recommend reading about Tasks and Back Stack as there are many different use cases. You are most likely interested in android:launchMode here as there are four different modes that will work in your Intent.
android:launchMode documentation
There is a great demonstration on the Google play store for this:
https://play.google.com/store/apps/details?id=com.novoda.demos.activitylaunchmode&hl=en
If anything, you will want to tag the Activity with singleInstance:
Same as "singleTask", except that the system doesn't launch any other activities into the task holding the instance. The activity is always the single and only member of its task.
I read somewhere that each time you call startActivity() to transition to a new screen, you are creating a new instance of that activity. This immediately raised a red flag to me.
In search of a way to prevent this issue, I read about using FLAG_ACTIVITY_REORDER_TO_FRONT. However I'm a little alarmed that this method is not used in any of the tutorials I've seen for opening a new screen in your app. So I think I might be missing something. I mean wouldn't you always want to make sure you're not creating a duplicate Activity? isn't this kind of a big deal and shouldn't tutorials address it?
I just want to make sure that I am understanding, and dealing with, this issue correctly, and using the commonly practiced way to transition between screens.
I understand in some cases you open a screen, do something, then close it using finish() and go back. But if an app has a complex 4 level hierarchy , and the user needs to be able to jump around between the screens?
I mean wouldn't you always want to make sure you're not creating a duplicate Activity
Most of the time you probably won't want to have two instances of the same Activity but I suppose there are situations where someone might
isn't this kind of a big deal and shouldn't tutorials address it
It is definitely something that Android developers need to know about and understand how to use. I would imagine that you may not see a lot of it in tutorials because most of them teach you the basics to get you started. When a developer is new to Android, they typically have enough to learn about the framework. And they normally show you how to do a few screens (which is often all someone may need). They expect you to learn more of the details by reading through the docs and using websites such as SO
I understand in some cases you open a screen, do something, then close it using finish() and go back. But if an app has a complex 4 level hierarchy , and the user needs to be able to jump around between the screens?
Yes, a lot of times you won't be getting too deep because the deeper the easier it is to get a "lost" feeling. This is why I like using Activities with a Dialog Theme when possible. It gives the feeling that you aren't actually leaving the screen you are on. However, that doesn't really answer your question. There are many flags that can be used with Intents to keep the stack from growing. The one you mentioned works and I also use Intent.FLAG_ACTIVITY_CLEAR_Top quite often if I need to clear all Activities from the stack and get back to one single Activity. There can be so many different situations between apps, users, and developers that how you transition and work the flow or navigation just depends on what you (really, the user) needs.
It seems like you are on the right track by asking these questions. Think about what will give the user the best and most natural experience and find the right flags in the Intent Docs for your situation
I hope this cleared things up for you a little. If you don't understand something, feel free to ask
You usually want to avoid creating a duplicate activity, and IMHO, it's a bug in the Android system that the default behavior is to allow it.
(Sometimes you do want to allow it, e.g. you've written a "get filename" activity, and more than one application is likely to call it.)
You control activity creation in two places: In the manifest, and in the flags of the intent that launches it.
In the manifest, the <activity> tag has the attribute android:launchMode, which can be one of:
"standard"
Default. Can be instantiated multiple times, can belong to any task, and can appear anywhere on the stack. Normally part of the task that called startActivity() unless the FLAG_ACTIVITY_NEW_TASK was used. A new instance of the class is created to respond to each new intent.
"singleTop" Identical to standard, except that if the target task already has an instance of this activity at the top of the stack, a new activity will not be created. Instead, the existing activity will receive a call to onNewIntent().
"singleTask" There can be only one. It's the first activity of a new stack, and is thus the root of an activity stack. If there are more intents, they'll be sent to onNewIntent().
"singleInstance" Identical to singleTask, except that it's the only activity in its stack. If it tries to launch a new activity, the new activity will start a new task. Same as if FLAG_ACTIVITY_NEW_TASK was in the intent.
I personally find the history back stack in android more confusing than helpful to end users. The use of back buttons can often not do what the user expects.
There are a few options available to you if you want to use activities as the main construct.
For workflow type activities (e.g. capture forms) start the first activity with Intent.FLAG_ACTIVITY_NEW_TASK and at the end use FLAG_ACTIVITY_CLEAR_TASK
For top level activities that are often a returning point start the activity with Intent.FLAG_ACTIVITY_CLEAR_TOP. This basically checks if the activity is already somewhere in the stack and if it is pops off every activity above it in the stack and resumes the original activity.
Another possible method for the top level activities is to use one top level activity and use fragments for moving around, e.g. tab browser etc. Then just use activities for actual separate tasks.
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.
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.
Under some circumstances I need to be able to tear down all my activities that are in my application stack and recreate them all due to configuration changes. I have accomplished this by first calling finish for each activity and then recreating the stack.
To recreate, I relauch my root activity. And within its onStart I have it create my second activity. Within my second activities onStart I have it create my third Activity. This does work but the problem that I am having is that when watching the screen you see each of the three activities created and animate into the next activity. I want to have this rebuilding invisible to the user and hide these transitions. Does anyone know how to accomplish this?
Android already takes care of restarting activities when there is a configuration change.
If you are saying you want all of your activities to be restarted, even if they aren't currently visible (Android will do this lazily as the user returns them and they become visible, if the configuration is still different at that point), then no there is no simple way to do this. I can't imagine you coming up with anything that isn't going to be hideously ugly, because to get the platform to restart your activity you will need to make it visible, and then you are going to have flicker up the wazoo.
Things just aren't intended to work that way. This isn't how pretty much any other application you run on Android will operate, so if you deeply feel like it is something you need to do then it will be useful to explain why that is so we can tell you a better way to accomplish what you want. :) For example, if you have a bunch of activities whose state is fundamentally tied together to require this, consider using fragments instead (or cleaning that up).
On the other hand, if you just have some internal concept of a configuration and want to get your activity to be restarted (say for example to switch between themes), there is an API for this but it only was added in Android 3.0: http://developer.android.com/reference/android/app/Activity.html#recreate()