Is there a way to have read access to history stack? - android

This is actually a very simple thing: I need to know if there is any of MY activities in the history stack? I'm not talking about other apps, just my own app. And I don't even need to know what are they or how many of them, I just need to know IF THERE IS ANY? Is there a way to achieve this? (ActivityManager.getRunningTasks().topActivity() is not for this purpose.)
(I'm implementing a backward/forward feature, as seen in many browsers. At first I tried to manage my own history stack and not use Android's at all. So I used noHistory=true for all activities in the manifest. This leads to the problem that the app's behavior is weird when it comes to the interacting with other apps or the Launcher. Now I tried to utilize Android's history stack for Backward operation, but my own stack for Foreward. But then it hits an unexpcted problem. .... Not just that, there is this security consideration in the app so that I can't let the user go back to any activity if the file has been locked up. I have to have total control over the stack.
Having been bothered by Android's activity life-cycle model and the history stack for several days. Extremely inflexible. How can they assume that all applications all activities in the world behave in the way they imagined in the lab!!!??? Seeing lots of people asking questions on the Internet in this area, and it seems to me everybody hit a dead end and then try to find some work-around, or compromise, or might as well change the spec. Android has been around for 3 years now, but they still didn't do anything to make it more flexible. I guess it must be a very fundamental thing in the design since Day One so that they know about the problem, but they can't do anything about it. Call it a wrong design.)
(And this non-blocking, non-synchronize dialog/message boxes. I don't know how they come up with this design. Whenever you want the user to confirm something, you have to break the program flow into several parts. This undoubtedly makes the program difficult to write and impossbile to maintain! If you have a series of questions one dependent on another, you might as well limplement a state machine.)

If you use Fragments in SDK level 11 and higher (so Honeycomb and certain Gingerbread levels), you can explicitly manage the stack. For regular Activities, you really don't have access to the stack, so you're out of luck there. You could possibly implement a personal stack using an application-level stack: storing the Intents you're using to launch Activities so you can move forward and then returning another Intent with the configuration data for each Activity (when each Activity finish()es you pass this state in the onActivityResult call back).
It would be very messy though.

Since you create and finish the activities, you should be aware of what is on the stack at runtime. Generally, you can control the stack pretty well. Take a look at the ApiDemo revolving around manipulating the stack.

Related

What are the reasons behind the change in the order of onSaveInstanceState and onStop for APIs 28+?

After API 28 the order of execution of onSaveInstanceState() and onStop() is changed.
Referring to this paragraph from the documentation:
The reason for that change is the ability to firstly execute fragment transactions and then save state. Referring to this paragraph from the documentation:
What are the gains after this change?
Are there other reasons behind this change?
It's indeed a matter of consistency, because method onStop() can still modify the instance state.
When moving onSaveInstanceState() to the end of the timeline, those changes will not be lost.
While I am not a Google employee and have not contributed to this, the change also affected activities if I correctly recall, and I'd imagine the reasoning has to do with the fact that before this change, the call to save the state, was maybe going to happen if/when the Framework considered somewhat appropriate after onPause.
The behavior was quite unpredictable and made the lifecycle methods unreliable to trust.
With (Google Devs) refactoring of the entire FragmentManager and its behavior, this change was most likely driven by consistency. (and unknown to me, perhaps, other technical details we're not familiar with).
In short, the framework is now consistent in the calls, as they are guaranteed to occur after onStop (for API 28+), which ensures that when you re-create the activity/fragment, the state will be correct (and saved).
Like I mentioned at the beginning, I am not a Google developer, but the way it was before was a clusterf**k of uncertainty, and this change brought some hope to save the Fragment apis from their ultimate demise.
Sometime in the middle of this, using multiple activities was not cool anymore, and we all wanted a single activity with many fragments, and nav component to seamlessly move across the stack (not having to worry to much about "defects" in the original design), as this and many other details were polished across the journey that got us here, to a more stable Fragment platform if you so desire to use it.
Before all these "fixes", the Framework API was prone to many errors and inconsistencies sometimes leading to runtime crashes. I can imagine how this and many other fixes, were aimed at reducing this API to a perfectly functional feature, so that other tools like Navigation Component, Lifecycles, ViewModels, etc. could all work in harmony without having to worry about "oh, the Fragments are special and need further logic to handle its buggy behavior".
Despite all this, Fragments are slowly starting to become "an old thing" as more apps start to incorporate Jetpack Compose.

Too many Activities in Android?

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.

Memory from activities not released

I've an application that has some foreground activities and also a service that updates some widgets.
The problem is that, as the process remains for the service, the memory from the other activities ,if they are opened, is never reclaimed.
Looking at that response from Roman Guy it seems that can be normal. But it is? For how much time android keeps the resources of not used activities? They can live for hours?
How can I know easily if the activities are leaked or are simple not reclaimed? I've tried with a program from AndroidMarket (FreeMemoryRecover) and it's cleared but I suspect that it kills the process and then restart the service...
Any help or suggestion will be heavily appreciated.
Note 1: I've investigated with a HeapDump + Eclipse MAT and I don't see strange references holding my activities
Note 2: I've already asked some questions about this problem:
Post 1
Post 2
The ability for Android to have multiple Activities, in different states, is a design principle as it allows users to quickly switch between activities without consciously having to shutdown whatever they were doing before. They can then quickly return to a previous activity.
If Android needs to pause an Activity, and quickly unpause it, it's going to need to keep the Activity's resources available to it.
If the memory is part of a terminated Activity, then it's leaked (very unlikely as the Linux kernel will reclaim all memory that was used when the process terminates), else it's either being actively used or is potentially about to be used.
What is that concerns you about this memory?
I would try the following :
Launch your app play with it to be sure it is fully loaded and use as much memory as it can.
Then hit the home button and launch the navigator, open techcrunch.com, lemonde.fr, youtube.com, dailymotion.com, launch a video from youtube, open up and play angry bird and last but not least open up a pdf document.
After that Android will have needed the memory back quite for sure. If your app is still there, you might have a problem, if its not, then everything went smoothly.
By the way, good on you to put so much concern in being a good citizen in AndroidLand !!
See my comment below your question.
See Romain Guy's post about Android memory leaks.
Specifically, look at the comment on the solution in the Launcher app. (look at unbindDrawables code here)
Use Context.getApplicationContext() whenever possible instead of your activity's context.

Pattern "One activity, multiple views": Advantages and disadvantages

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.

Android: Repetitive Android Activity Workflow. Fire and Forget?

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.

Categories

Resources