hey people,
I have almost finished writing my first android app. It is a note taking app with add, edit view screens etc...
Initially I was handling moving between screens in a single activity by creating new layout objects such as tables etc... and displaying them.
However after some more reading I have changed my method of moving between screens by using different activities for different screens. However each activity that is called as an intent retrieves a large number of variables from the main activity via setExtra and passes back a large number of variables as well.
Now I want my app to be as efficient as possible and I personally think that handling it all in one activity is less memory hungry and processor intensive although this has the negative of meaning variables are always present (and consuming memory) unlink in a separate activity where they are killed on finish().
But you guys are more knowledgeable then me so what do you think is the best way to do it?
If you launch a new activity for the new screens then you will add that activity to the stack. That way a user can press back and get back to the previous activity. Just changing the layout removes this functionality. I doubt very much you'll have performance issues either way.
Best practice would be to start a new activity, best performance might be to use your current approach.
All your activities will reside and run from the same process. So there is no reason you need to pass around a pile of variables. You could (for example) stick them in a singleton which represents your context. When one activity hands over to another it fills in the singleton and the next one picks up its data from there.
Of course if you ever intend an external activity to interact with your ones you may have to rethink this approach, but I think you'd be fine to keep your views as separate activities. Even if memory is ever so slightly higher, I think it's better to do things correctly and only worry about optimization if and only when it becomes obvious you need it.
Related
There is a settings screen with multiple categories and each category has 5 to 6 its own settings. Just imagine settings screen of Android OS.
Now, to avoid having Set button on the bottom and trying to implement application of changes immediately upon a user changes any settings (thus to gain speed in the app and to have a better user experience), I thought of having dozens of AsyncTask classes, each implementing just a simple thing.
For example, there is a settings screen with 4 things to set. A user changes setting no.1 and I immediately call AsyncTask for that specific setting in the background. And like this for each change a user makes.
How smart is to do this? Would this overload AsyncTask idea or even come to the point that too many AsyncTasks are called consequently (I read that there is a limit of AsyncTasks that can be called, 5 or something)?
Is it a better design to call 1 AsyncTask with all changes when a user leave the specific settings screen?
Note: I am not asking here how to implement AsyncTask. My questions is directly bound to best design and the best speed of the app, as well the best UX.
You should not use asynctask when you have more than 1/2 operation(s) a minute or so (Quote in Android pushing the limits). You allocate a lot of objects and I peronally found that it looks like the Asynctasks are waiting on another. Maybe use a handler/runnable.
On a site note, you can save all the changes in variables in memory and then periodically save the settings to a backing store. There is nothing faster than just setting an instance variable/array.
In our application when a user switches between modes (different user/ different type of screen) the activity recreates itself (by an explicit call to recreate() ). This behavior was added by a external programmer we hired. He states this is completely normal to do.
The problem I have with this is that 99,9% of all activity state is the same. But when the activity is recreated all data is queried again, consuming quite a bit of time.
Is this a normal pattern? Or is it just as good to only change the data to suit the new situation?
To me it seems kind of strange to manually recreate the whole Activity just to reload some data. In any case just updating the data which has actually changed seems like a much better approach. Especially if you say that it takes quite a bit of time to reload all the data.
The only thing I can think of right now which requires to recreate the Activity is changing the locale or something like, but even that I would not recommend unless it is really necessary. If you are not dealing with configuration changes, e.g. locale, there is no reason to recreate the whole Activity just to reload some data.
I would say it's "normal" in the sense that Activities are recreated all the time by the system, so this just adds another event in which that would happen. Though this is, on it's own, really weird way of going about it. A better, more efficient, cleaner way would be to swap out Fragments on "mode change". You can have a UI fragment for each "mode" and the data stored in a retained Fragment that each one pulls from. This would also help in the sense that the UI doesn't have to be recreated completely with each Fragment swap.
However, if you must, it is an absolute requirement that you follow the same data storage/retrieval methods that you would if the system was killing and recreating the Activity. See How to save state during orientation change in Android if the state is made of my classes?
Basically, you shouldn't be recreating data you already have.
When i started my Android project i had a misunderstanding that every screen that's shown in the application must be a new activity. Now i am finished with the project , i have checked it on my emulator as well as on a couple of android phones. So far i am not witnessing any problems, but recently i read somewhere that too many activities in the application are a pretty bad idea.
Currently my application has around 15-20 activities.Ideally i heard it should be around 5-6. Do i need to re-structure my code or just finishing every activity after it has done it's part is enough?
While creating complex applications you definite need to create many activities. So it depends on your application how many activities you need. No of activities in a project do not affect the performance.
The effect is produced by the number of activities in the stack of your android. So it is better to keep 5-6 activities in the stack(Finish activities if they are not needed any more).
So create as many Activities as your application demands but keep smaller no of Activities open at a time.
If your project has many activities but some activity is not important,it means that you do not need any activity after another activity start.
In manifest file set : android:noHistory="true"
Example:
Activity1 -> Activity2 -> Activity3 -> Activity4..................-> Activity20
In manifest file:
activity android:name=".Activity1" android:label="#string/app_name" android:noHistory="true"
if u call again Activity1 using Intent than set finish() before startActivity()
I think this can help you
The Android system tries to maintain an application process for as long as possible, but eventually needs to remove old processes to reclaim memory for new or more important processes. This applies to Activitys that are running in the background... old Activitys are managed for you and are destroyed when the system needs to reclaim memory for new processes.
That being said, I think there are two things you should consider:
User experience. Does your app really require 15-20 Activitys? Can you cut down the number of screens somehow? Less Activitys is usually better, since it requires less interaction when the user is navigating the application.
Code design. While each Activity will have its own separate class, this does not restrict you from making smart design-decisions when implementing your application. For example, you might try grouping similar Activitys by having them extend an abstract class. As Android projects grow in size, they become more difficult to manage. Sharing code amongst similar classes in this manner will ensure that you can make simple changes to the core of your application without too much trouble.
[EDIT] - As of Google IO 2018, Google recommends using a single activity with many fragments. Something to consider.
It ultimately depends on what you're doing. There are some times when you can not modify the view enough to make a difference. Ideally, 5-6 activities is great, but some cases thats not just not doable. I've done a mobile app with around 40 different classes, and about 18 activities. It just HAD to be done that way based on how the app was to interact with the user. If you can merge 2 or 3 activities into one, thats great. It'll help with file size and optimization as well, but if you can't- Don't fret on it too much.
I would say 15 different screens = 15 different activities. I think one of the reasons some are able to reduce the number of activities is because of the introduction of fragments. Although one will argue why use fragments if individual activities works. I guess it depends on the developers preference.
It's better to use fragments than activities. We can use multiple fragments in single activity so we should always consider using fragments. I've seen complex applications with 5-6 activities and 150+ fragments.
This pattern is similar to the pattern Main Servlet (the Front Controller) that is used for developing web applications.
The main idea of this pattern: we have one Activity that manages multiple views and this activity is responsible for representing current content. Not all views need functional of activity (e.g. life-cycle methods) so the main question is: if I can go without activity why do I have to use it?
I have found the following disadvantages of using this pattern:
Official source doesn't recommend to Overload a Single Activity Screen
but they don't explain why.
We cannot use TabActivity, ListActivity, MapActivity. But there are some tricks to go without them.
If different screens have different menu it's a problem to make that without activities.
It is necessary to keep history by ourselves. But it's not so difficult to develop.
I have found the following advantages of using this pattern:
It's faster to change the content of current activity than to start another activity
We are free to manage history as we want
If we have only one activity-context it's simpler to find and solve problems with memory leaks
What do you think about this pattern ? Could you provide any other advantages/disadvantages ?
We cannot use TabActivity, ListAcivity, MapActivity. But there are some tricks to go without them.
You have to use MapActivity if you want to use MapView. You have to use PreferenceActivity if you want to use preference XML.
It is necessary to keep history by ourselves. But it's not so difficult to develop.
The difficulty in managing your own history will depend greatly on what the history needs to be. Implementing history for a simple wizard will be fairly easy. However, that is a particularly simple scenario. There is a fair amount of history management code in Android that you would have to rewrite for arbitrary other cases.
You also forgot:
#5. You will be prone to leak memory, because you will forget to clean up stuff, and Android will not clean up stuff (since it assumes that you will be using many small activities, the way they recommend).
#6. Your state management for configuration changes (rotation, dock, SIM change, locale change, multiple displays, font scale) will be more complicated because now you also have to figure out what extra stuff (e.g., history) need to be part of the state, and you have deal with all of them at once rather than activity-at-a-time.
#7. Having multiple entry points for your application becomes more challenging (e.g., multiple icons in launcher, app widget linking to some activity other than the main one, responding to etc.).
It's faster to change the content of current activity than to start another activity
For most modern Android devices, the speed difference will not be significant to most users, IMHO.
If we have only one activity-context it's simpler to find and solve problems with memory leaks
Except that you still have more than "one activity-context". Remember: your activity, large or small, is still destroyed and recreated on configuration changes.
What do you think about this pattern ?
Coase's "nature of the firm" theory says that businesses expand until the transaction costs for doing things internally become higher than the transaction costs for having other firms do the same things.
Murphy's "nature of the activity" theory says that the activity expands until the transaction costs of doing things internally become higher than the transaction costs for having other activities do the same things. Android developers will tend towards a "user transaction" model for activities -- things that are tightly coupled (e.g., steps in a wizard) will tend to be handled in single activity, and things that have little relationship (e.g., browse vs. search vs. settings vs. help vs. about) will tend to be handled in distinct activities.
This will be horrible to maintain if new functionality is added later on.
I'm also not convinced it will be so much faster that the user could notice.
Having components as smaller pieces that are easier to change or swap out is definitely the way to go.
I am working on an application that tries to streamline data entry from a very repetitive process:
Enter some details that require full-screen graphics and would be confusing if scrolled
Enter some more atomic details
Enter yet more atomic details
Apply the accumulated data
Go back to step 1
I am pretty sure that i can represent this as 3 separate Activities and then just fire up new Intents for each activity in each cycle. What I can't yet get a sense of is whether this is a viable approach.
Question 1: If I do a fire-and-forget approach, how much of the resource management is going to be handled by Android? Will it just happily deallocate/reuse/etc. activities behind the scenes? Or is this something i have to manage myself?
Question 2: Is there a way to cause the reusing of activities so that only one instance of each activity is ever allocated and is just reused for each cycle?
Question 3: Can one manipulate the activity stack so that there aren't ~100 (approximated number of expected cycles) cycles worth of activities on the stack? I'd like to be able to use the back key no more than three times and exit out of the data entry portion to a summary page.
Question 4: Can anyone suggest alternate approaches to the cycles of activities problem? I have considered view flippers and tabs, but wasn't sure that would be better or not.
Will it just happily
deallocate/reuse/etc. activities
behind the scenes?
Yes.
Is there a way to cause the reusing of
activities so that only one instance
of each activity is ever allocated and
is just reused for each cycle?
Try FLAG_ACTIVITY_REORDER_TO_FRONT on your Intent to launch the activity. Based on the docs, it should give you your desired behavior.
Can one manipulate the activity stack
so that there aren't ~100
(approximated number of expected
cycles) cycles worth of activities on
the stack?
100? You must be expecting some very patient users.
Regardless, FLAG_ACTIVITY_REORDER_TO_FRONT should cover that too.
Can anyone suggest alternate
approaches to the cycles of activities
problem? I have considered view
flippers and tabs, but wasn't sure
that would be better or not.
Tabs aren't great for things where you're trying to enforce a flow, since tabs are designed for random (not sequential) access. ViewFlipper/ViewSwitcher could work, though then you have to manage BACK button functionality and make sure you're not effectively leaking memory within the activity, since you're expecting people to be using it for an extended period.