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.
Related
In my UWP-App I want to create an app internal contactbook page. I can select a contact and return the selected contact back to the page where I opened the contactbook.
In Android where I come from there is a function called "startActivityForResult" which opens an activity gets the return value when finished.
I want to create the same behaviour.
I did this with Frame.Navigate(typeof(ContactBook)) and then when the contact is selected I navigate back with Frame.Navigate(typeof(PreviousPage), selectedContact)
The method Frame.GoBack() is useless in this case because I can't pass a parameter.
How can I solve this problem?
I'm not 100% familiar with android and "startActivityForResult" but are you looking to navigate the entire frame away? There isn't any equivalent in UWP apps, nor is there even really one for WPF's showDialog(), which is probably what you're looking for.
You only have a few options and none of them are really "amazing" per-say.
You can do what you've done above, which is navigate away to the page that has all the contacts, then navigate to a new page but depending on how your app is layed out you might be losing data on the page (since it's a new instance and not a back in the stack so you can't really cache it). You also can't navigate to an instance of a page either, it's only to a new page or through the stack from back / forward. If you use GoBack though and cache the page (using the "required" mode for caching) then you could do some dirty lookup of a stored value in a static class (I know, ugly and not MVVM) or setting a local settings value and reading that in the OnNavigatedTo() method for the page before.
If you don't NEED to use frame movement, you can use a flyout or a custom flyout user control to build a popup of sorts that will display the XAML for the page instead of a page frame. This will have a few difficulties with resizing (so more so for W10 than W10M) and such but you'll be able to not transition out of the frame itself. Then you can see the value of the selected and then on the submit event, you can just work with the page since it's already open.
If need be you could build a custom usercontrol for the flyout and put some custom dependency properties that can be bound for MVVM, it really all depends on what and how you're doing it.
So short answer, there is no fast way of achieveing what you're looking for and that does seem like an issue with the API. I would make the suggestion on the API's uservoice (https://wpdev.uservoice.com/forums/110705-universal-windows-platform) and try to get it upvoted!
There isn't any equivalent in UWP apps, nor is there even really one for WPF's showDialog(), which is probably what you're looking for.
#Daniel, no, there is a equivalent in UWP apps. Please refer to Launch an app for results, you can follow the tutorial in that doc to achieve this.
To do this, you will need to create two apps. One is the app which will launch the result app (let say "main app"), the other app here should be the contact-book app. The contact-book app will behavior like a modal window, and the main app will wait for the result of the contact-book app.
But in an UWP app, you can use ContactStore class to access the database that contains contacts.
So, you will need to reconsider if that is necessary to create a contact app by yourself.
Edit:
I may misunderstand your question, you just want your page to behavior like contact-book, not want to create a contact-book by yourself. But anyway, it's the same, you can create another app to hold your page which you want to launch from your main app.
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.
Some days ago I have published my application in Android Marketplace and a question came into my mind during designing and developing application. This question is about limitation or unlimitation of number of activities.
For example, my application includes 37 activities. Is it so much? I want to know for a game such as "Angry Birds" which has more than 200 levels, it has 200 activities?!!
My next question is, assume that I am designing an application which includes 100 activities. User starts application and gos into last activity (such as reading a book). If user wants to close the application what should he do? 100 times press back key on his devise?!
If I want to put close button(to help user) in options menu, do I have to repeat it for each activity? because as far as I know each activity has its own menu.
If i put close button in last activity and user clicks on it, program will close. What will happen to other 99 activities? are they still exist in stack? or When I close an application, all activities related to that package will delete from stack.
I have read activities page published by Android but I couldn't find my answers.
Sorry if above questions are stupid questions :)
Thank you
In the case of Anry Bairds, I doubt they have 100s of activities, I think they just have one (or possibly a couple) for levels and another for the welcome screen - different levels are probably loaded depending on some parameter that was passed to the activity.
As for how to handle 100s of loaded activities, first of all, it is very likely that the system will recycle the old ones at the bottom of the stack before you get to the 100th activity. If not, then yes, your user will have to click back through a 100 activities.
If you want to change the behaviour of what the back button, you can override onKeyDown().
Or if you want to change the default behaviour of how activities are launched, then take a look at activities launch mode.
Please read Tasks and Back Stack and Activity and Task Design Guidelines
Well, first, regarding angrybirds, I guess it is written nearly entirely in OpenGL ES, so it consists of only a few activities.
And second, if you're really having 200 activities, you should probably think of an activity which can be reused multiple times. e.g. why would you need one activity for every page of a book, if every page should have the same look and functions? Just fire an intent with extra data and it should work. And, to close the app, you can simply press the home button :-)
An application like Angry Birds probably has one activity with an OpenGL ES view, with all of the interfacing done with a RelativeLayout
that being said, you could have an unlimited number of activities, the only concern is how much space your app will take, why any user would want to navigate through such a robust program on their mobile device, and how much RAM you are using and are you managing your activities efficiently
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.
I have developed some apps for Android, and this questions stays always:
How should I structure my UI? Should I launch activity after activity and leave the phone to make the "back" button, or should I choose more optimized, but more complex to implement, way with switching manually Views and then manually doing the "Back" button functionality?
What do you think (or know) is the better practice?
I would say that multiple Activities almost always makes more sense. I just don't think Android is designed for constantly switching its own views - you miss out on so much. You have to implement Back yourself, you don't get any inter-Activity transitions, you have to implement a lot of internal logic to resume an application in the correct state. If you don't partition your app into Activities, it makes it a lot more difficult later on to change the flow of your application. It also results in one mega-Activity that can be a lot harder to handle than a lot of smaller pieces of code.
I have trouble imagining that speed is really an issue; if it is then there's something wrong with the way you're initializing each Activity. For example, I used try to pass Serializable objects between Activities, and that proved to be incredibly slow; when I switched to a faster method of passing objects, the speed of launching Activities increased immensely.
Also, I think it's telling that the Android guidelines for Activity and Task Design don't mention switching Views at all; it's centered around an Activity-as-View design.
I'd like to point out some instances when a single activity might be better design for an Android application that has more than one full screen View:
If the application screens are tightly coupled and share a common Object that they are all operating on. In this case passing around the Object may require a Bundle and can be error prone since there will be copies of it. A good example might be a wizard. Yes you could use static's to access the common Object but static can be dangerous in Android (think configuration changes!)
If you want some really cool animations in between screens. Maybe you want a bird to take off in one screen and land in another screen. Try doing that when each screen is an activity!
On the other hand if one of your screens is designed to be shown by any number of other applications then that screen should be its own Activity.
UPDATE March 2014:
At this point the question should now include the choice of Fragments. I think that Views are probably the least likely choice of the 3: Activity, Fragment, View. If you want to implement screens that make use of the back button then it should be either Activties or Fragments because both handle the back button natively. Fragments will need to be added to the FragmentManager back stack for the back button to work. Managing fragments, dialogs and the back stack can be a bit of an annoyance though!
UPDATE Sept 2018:
Some devs at Google are recommending single activity apps using the new navigation architecture component.
Also keep in mind that implementing your app with multiple Activities will give the user a more coherent experience with the platform as a whole. Part of the experience will be shaped by using the built-in Google apps, so users will probably have an easier time using your application if it behaves similarly to the ones that are already installed on the phone.
Different from others I use a mixture of both, for example,
1. There is a main menu when the application starts
2. You click on search, takes you to search activity
3. Then there's a filter button, which just switches view and shows you filter options
4. There are two buttons at the end of the filter view, You hit "Search" or "Cancel" and you are back to the Search View again (without switching activity)
5. Now if the user hits the phone back button he's taken back to the main menu instead of the search filter options. Which I guess is the correct behavior.
Use it the way user will feel natural. And keeping everything in one activity will make it complex.
It all depends on application, what are you trying to achieve better performance, smoother UI. IMHO I prefer the second approach of controlling the Activities manually even that it is more complex as you have stated. This is a approach I have used in my android tabs project, also you might want to take a look at a class called ActivityGroup (not sure the package) it allows you to have multiple activities that you can switch between, good thing about this class is that your activities are not unloaded when you switch but a bad thing is it takes longer to load your main app.
Just my opinion.
The problem with switching views, that I stumbled upon, is also caused by garbage collector. Seems that GC is triggered when you leave activity and not the view. So, changing tabs with a fairly complex children views, for instance, will almost inevitably lead to stack overflow exception..
I've experienced so many problems with multiple activity layout that I strongly discourage it, unless there's good reason to pick it.
Disadvantage of multiple activities
Using multiple activities it is much hard to refactor code to return data from activity.
If you call a 'sub'-activity then the main activity may be killed. But you never experience that while debugging on a decent device, hence you need to handle always saving state and correctly recovering state. That is a pain. Imagine calling a method on a library (ie. another activity), and you would have to be ensure that when that method returns your app must be able to recreate its state completely with all fields on all objects in the VM (ie. activity.restoreIntance). Its insane.
Also the other way round, when you open a subactivity the VM might have been killed since the subactivity was first spawned, such as when app is minimized while subactivity is displayed.
Its so much cleaner to just have one place to store the relevant app-state, and in my case, most often if VM is killed, I want to return user to main-screen, and let them do their stuff again, because I don't spend 30-50 hours coding save/resume functionality that 0.1% of users will ever experience.
Alternative
Fragments or just manage you activity views yourself. Managing views manually, requires coding some view-switching alternative to activities/fragments with transitions if desired.
And no it does not mean one mega-activity, as suggested in the accepted answer, in any other way than its one mega-app. It just requires a bit more design of the codebase into fitting pieces, because there's slightly more work managing views, though much less work managing activity-state and other weirdness.
Possibly relevant: Reddit: It's official : Google officially recommends single activity app architecture