Android launchMode and "infinite" SettingsActivities - android

I have huge problems, to understand the launchMode of Android apps or, let's say, I struggle to understand, why singleTask isn't the "wanted" or desired default option.
I can't imagine actually any advantage of having or wanting to have more than one active running activity (GUI) instance. It would make sense, of course, if the activity was a sub GUI, where you maybe want to have multiple "tabs", for example in a web browser, file manager, etc. But those are very specific examples, and for a normal app GUI, does it make sense to allow multiple instances of the same GUI frame? On a desktop, there is always one GUI instance, never multiple. One settings instance, one sub settings, and so on. And if you closed the window, you always go back to the one instance of the previous frame.
I noticed this actually really fast, after I implemented a SettingsActivity (AppCompatPreferenceActivity) via the default activity template of Android Studio. The problem now was that my app created "infinite" sub setting menus if I went forth/back/forth/back in the settings activity. When I was now pressing the back button, I ran into the this problem:
submenu1 > menu > submenu1 > menu > submenu2 > menu > submenu2 > menu... > mainacitivity > app closing
Of course, although this can't be the desired behavior, still it's given as default behavior by Android Studio, and as I understand, is the normal behavior for launchMode=standard (or not putting it in the manifest file anyway).
For a SettingsActivity, it just doesn't make sense in my understanding to have more than one running instance, and if the user pressed the back button in a sub menu, it should always bring him back to the menu before, and if he's in main menu, into the activity before that.
So how can I change this? or is my whole understanding just wrong? Should a SettingsActivity be set as launchMode=singleTask? Or how did I get into this infinite loop of back and forth by pressing the back button, if I went into sub menus "too often" before?
I actually read somewhere before, that you should avoid using launchMode=singleTask, but I don't know why. In my understanding a singleTask would just make more sense, for mostly every situation. How would it make sense to allow multiple instances of any GUI frame...
Hope this isn't a stupid question. I tried to find a satisfying answer to this, but I couldn't find an explanation really to my questions.

Related

Android: Tabbed App with Navigation Stacks

I'm working to clone an iOS app that uses a UITabBarViewController as the "main/outer/root" UIViewController. Each of its tabs has a UINavigationController as the root to manage a navigation stack of UIViewController instances.
I am trying very hard to do 2 things:
Replicate the functionality of the iOS app.
Do so in true "Android" fashion (i.e., not forcing an iOS paradigm in a non-iOS world).
I've searched around a good bit, but this topic seems to have been changed a lot over the past few years. I tried a solution that had a single Activity that managed everything, but that required maintaining separate back stacks, and seemed to get a thumbs down from most users around here.
Currently, I have a solution that is "sort of" working. As I understand it, my current setup is:
A single, BaseActivity class that extends ActionBarActivity.
All activities in my app (only 2 thus far, but slated for 5) extend this class.
This base activity loads a drawer.xml layout, which has an android:support.v4.widget.DrawerLayout as its outermost item.
Inside of this is:
A FrameLayout, which is the container for my fragments.
A ListView, which is the drawer itself.
Based on my testing of the app, this setup gets me most of what I want.
When I "navigate" (using the drawer) to a different activity, the correct activity is loaded.
When I "navigate" to a "deeper" fragment (via on-screen controls), the correct new fragment is pushed and I've overridden onBackPressed() in BaseActivity to correctly pop the back stack if appropriate.
The problem I'm encountering is this:
The app is launched and "Activity 1:Fragment 1" is displayed. I click on an item to move to "Activity 1:Fragment 2" (which works well).
I use the drawer to launch Activity 2, and "Activity 2:Fragment 1" is shown. So far, so good.
I use the drawer to go return to (at least that's my intention) to the existing Activity 1, and "Activity 1:Fragment 1" is displayed.
I've looked into Activity/Intent launch flags, but I'm not sure I really get what's going on. So far, my reading has led me to try the following steps:
When switching Activites, setting its flag like this:
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
In my AndroidManifest.xml, setting Activity launchMode like this:
android:launchMode="singleInstance", or like this
android:launchMode="singleTop"
An odd, additional problem I'm facing is that launching a new Activity doesn't seem to create the Activity back stack like I expect. When I move from Activity 1 to Activity 2 (ignoring the lack of fragment back stack maintenance for a moment), pressing the back button from Activity 2 closes the app, which confuses me.
Is there a single, current best practice for this type of app structure/navigation?
the good approach is to have 1 activity and handle the back stacks manually as Android has only 1 stack. I've done this several times and finally I created a library called Tab Stacker that does the job: a fragment history for each tab.
It is open source and fully documented, and can be included easily with gradle. You can find the library on github: https://github.com/smart-fun/TabStacker
You can also download the sample app to see that the behaviour corresponds to your needs:
https://play.google.com/apps/testing/fr.arnaudguyon.tabstackerapp
If you have any question don't hesitate to drop a mail.

Refactoring from Fragments to Activities

This is a bit of a desperation call for some good advice.
I began doing a project which involves Navigation drawer as the main menu for the application. After looking at the Android tutorial I followed the example and start developing on top of that. That example is a single activity that replaces the fragments depending on the selected option in the drawer. In part, I followed this design because if I launched Activities the drawer was lost and the Activity would appear with the launching transition and didn't look nice at all.
Now, my project is not a small one. During development I faced several issues like:
onResume not being called on the Fragments (due to not being attached to several activities but one instead.
All the data between Fragments should pass through the single Activity
Managing the Options Menus in the ActionBar became a real pain.
And many others I don't recall now
Now I am facing a new issue. In one of the fragments I need to have a Spinner that will switch fragments inside this one. And of course, the fragment will need to change the navigation mode in the action bar. This was a major headache to develop, but now I am facing a bigger problem with some fragments inside losing the activity context (like if they were detached).
After so many problems I just decided to switch back the whole app to Activities (this is a custom app that will run in just 1 tablet model, so no worries about fragmentation). So, in short I am looking for advice on the less painful way to do this.
I am on a extremely tight deadline that lead me to start implementing without designing (like a complete noob). Now I am being hit with so many issues that, if I didn't need the money, I would cancel this project at once.
Please help!
I can give a little advice, but sadly your situation can't really be solved by any one answer here.
First off, switching from a Fragment design to an Activity design is a lot easier than switching the opposite way. You can actually use all of the fragments you had before, and just have each activity loading only 1 of the fragments (or multiple if you prefer).
Also, when handling Intents (starting new activity), after the startActivity() call you can call overridePendingTransition() to make the launching transition whatever you want (or remove it completely).

switch to a new activity, instead of switching fragments, when jfeinstein10's slidingmenu list item is clicked

I have seen a few questions raised on this topic (for e.g.: https://github.com/jfeinstein10/SlidingMenu/issues/5) but I am still unclear. I hope somebody can clarify this.
Context:
See https://github.com/jfeinstein10/SlidingMenu
I have an android app that organizes screens by activities and fragments (i.e.) each screen is an activity containing one or more fragments.
The new requirement is to add a sliding menu (similar to what this library provides).
Issue:
It appears from the examples and discussion that the right model would be to have just 1 MAIN ACTIVITY that will then switch in/out fragments belonging to the different screens. In fact the author mentions in the above thread: "If you were to launch Activities based upon the list selection, then you would not have the behavior where you swap the views that you're talking about. " and also "You can't put an Activity into the above view. That doesn't really make sense when you think about what an Activity is. ".
Why doesn't it make sense? Obviously, I am missing the point here.
Question:
Given that my project already contains multiple activities (one corresponding to each screen), is my only option then to re-organize the project to have JUST 1 MAIN ACTIVITY, in order to use this library? Or alternatively, is there any way to launch a new activity when a list item in the sliding menu is clicked, and still observe the sliding menu behavior, [EDIT- added the last part to be more clear] or in other words, on how exactly to use this library within my existing app design.
Thanks in advance
First, you can't have an Activity inside another and activities are completely different from views as stated in the docs:
An activity is a single, focused thing that the user can do.
Now, to answer your question, it all depends on how you want your app to behave. You could have your activities with the sliding menu implement the onClosedListener and switch to the selected activity from there. This will give you the animation of closing the menu before switching activities. It will also give you a weird effect since every time you select something from your menu you'll see the animation of a new activity coming to the front.
I think the best approach would be to have a "common purpose" between all your sliding menu options. For example, in one of my projects I have to allow the users to select between lists of different types of data. When the user selects anything from the menu, I load a new list fragment into the right corner where he may choose the item he wants to view or edit. That's the app entry point and also the only place were I have a sliding menu in my app. It is pretty much the same for every app that implements this UI design pattern. Look at google+, currents and youtube where the side menu lets you choose which feed or content to show. Once a user makes a selection, just open a new activity for the selected item (a g+ post, a video, a news article, a tweet or whatever it is).
Your app doesn't have to have lists of different data or anything like that to use the sliding menu, but keep in mind that the activity with the sliding menu should have a clear, focused goal with respect to its functionality and purpose. Having a sliding menu because many other apps have one is a bad choice, you should use it with a specific objective. Also keep in mind that applying the sliding menu everywhere would interfere with the platform's navigation pattern and lead to an overall bad user experience since it wouldn't behave as the other apps.
It doesn't make sense to place an Activity into the above view because the Activity is the main controller for the view of each screen. The Activity also shows views and keeps track of Fragments (which in turn are mini controllers, with or without their own views). So placing an Activity in the above view would mean that you would place an Activity in an Activity... Wich is impossible.
From what I can derive from your text I think it would be wise to read through the Android developer guide on Activities and Fragment again (http://developer.android.com/guide/components/activities.html) to get a better understanding of how the concept of Android works.
Now to your question:
I am not clear on what you are trying to achieve but if you want your app, with menu to behave like, say, the Google+ app then one way of doing it is to implement a base class that extends the Activity class (or what ever base Activity used in your project) and let the base set the SlidingMenu. Then you would simple extend your base Activity in each of the Activities that are supposed to have a menu.
You could also do it the way you describe it, but then you would end up with a classic example of a God object (http://en.wikipedia.org/wiki/God_object). It's a neat way to practice your Fragment juggling skills and switching between Fragments instead of starting new Activities does have it's use cases, but I still wouldn't recommend it for a project with more then a few views.
Here is the answer that came closest to the issue I had - http://www.verious.com/article/polishing-the-sliding-app-menu/. Scroll down to the bottom of the page to see the last section titled "Using the fly-in app menu between Activities". This is one option if you have a lot of activities in your existing app and want to avoid extensive re-factoring. I haven't tried this out yet but its worth being aware of.

How to manage multiple Activity stacks in an Android app, like you would on iOS with multiple UINavigationControllers within a UITabBarController?

A fairly common model for iOS apps seems to have a single UITabBarController, where each tab essentially holds a UINavigationController, i.e. a stack of controllers, and pressing a tab switches to the top of the corresponding stack. Can I get the same behavior on Android without a lot of custom code? (Note: I am using menus instead of tabs on Android).
After reading http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html the closest I can see is to have multiple tasks, each one representing a stack (akin to UINavigationController), and to use FLAG_ACTIVITY_NEW_TASK to switch to another task/stack. When I switch, is there a way to go straight to the top of the stack, or do I need to keep that piece of state myself?
One problem with keeping that state myself: I've noticed that if my app launches an Intent that starts a new process, sometimes my original app's process is killed (I think), and all of my global state is destroyed.
The only other solution I can imagine is to have a dummy Activity per stack, to push DummyActivityN essentially right before I switch away from the Nth stack, and, when switching to the Mth stack, to start activity DummyActivityM with FLAG_ACTIVITY_NEW_TASK, and then have DummyActivityM immediately finish() itself.
One last problem: as I navigate to the bottom of one of the stacks, with the back button, I would like to hit the back button once more and NOT go to another stack/task. But this seems easy to overcome by launching an Intent to go to the home screen; is there anything better?
If I understood your problem correctly, if you add this parameter to your Activity declarations in AndroidManifest.xml, the Activities that are launched by your custom menu will be only created once - keeping their state while you move around the tabs.
android:launchMode="singleTask"
I hope this helps,
Best,
-sekran

Android: Adding Activity to the menu on the homescreen

I'm trying to add my Android activity to the menu on the homescreen (the one with: add, wallpaper, settings, search, notifications).
I suspect this is done from the AndroidManifest.xml, but I can't figure out how.
Am I looking at the right place? And if so, what am I missing?
You can't add your application there. That's controlled by the "home activity" which you don't have control over (for good reasons, otherwise anyone could add anything there).

Categories

Resources