I've noticed while trying to switch from one Activity to another within a glass app I've built, the menu seems to get messed up and I get left with a ghost activity displayed in my LiveCard that cannot be closed.
I've reviewed a few of the examples (e.g. Compass) but we don't have any advanced examples for navigation it looks like. Can you help out with defining for me the agreed upon convention thus far for building navigation in apps? This will help fix my issue because I realize I'm creating multiple LiveCards which doesn't seem right.
Activities: Should I create multiple activities or should I recycle the same Activity swapping out the UI instead? If multiple activities, is it a good idea to destroy the previous Activity's service upon loading up a new Activity?
Services: In a broad sense, should there be a single service used by all activities to handle the navigation (switching between Activities)? If just one service, should it ever be stopped/restarted? How do you switch between Activities using the service because we don't have a reference to the service from the Activity or the Binder? Or should there be a service for each Activity to handle the navigation?
LiveCards: I believe only one livecard should be created, so then how do you switch between Activities without creating a new one? Is it the convention to keep a global reference for any service to be able to use this LiveCard?
I've asked a lot of questions and I could be way off base for some of them, but I can use any guidance! I can't really find a good guide on google for defining the expected behavior for nagivation. I come from 3 years as an Android dev, so feel free to be complex in your answers! Thanks guys.
EDIT:
In case this helps, here's the code I'm using to go from one Activity to the next:
mLiveCard = new LiveCard(this, GlobalConstants.LIVE_CARD_TAG_ACTIVITY2);
mRenderer = new MainRenderer(this);
mLiveCard.setDirectRenderingEnabled(true).getSurfaceHolder()
.addCallback(mRenderer);
// Display the options menu when the live card is tapped.
Intent menuIntent = new Intent(this, Activity2.class);
menuIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
mLiveCard.setAction(PendingIntent.getActivity(this, 0, menuIntent,
0));
mLiveCard.attach(this);
mLiveCard.publish(PublishMode.REVEAL);
We're probably all pretty new to GDK so I'm certainly not more of an expert then you.
I'll share with you what my experience is so far:
Activities:
I only use these when i want to create Immersions. I think the only reason to decide if you want to have multiple or one activity should be readability. If an immersion is all you need then you can start your activity directly instead of using a service.
Services:
I found it useful to have one central service. Especially in projects where I have state full objects with a lifecycle that spans multiple activities. In case your navigation depends on the state of e.g. a connection it also makes sense to let the service manage the navigation e.g. start new activities. Activities can interact and provide results to the service with whatever method is appropriate e.g. Intent, Broadcast, Binder, Singleton...
I usually go through the list and take the first one that fits the requirement. If i can do what I want to do with intent's then that's usually my first choice.
LiveCards:
A central service would also be a good place to manage a livecard that you want to share across other activities. Again the method to expose the live card interface to activities depends on what kind of interface you want (abstract vs direct).
Let me know what you think.
Related
I'm writing my first android app, and it's going very well so far, but my code is getting obtuse and I'd like to reorganize it in a way that allows me to reuse portions, and add things more easily.
Based on my previous experience writing simple command line programs that call methods, this is how I THINK I should organize my code:
(some code in MainActivity)
Call a void method of the object DoStuff:
Launch Activity1 and write some values to SharedPreferences file, THEN
Launch Activity2 and write some values to SharedPreferences file, THEN
continue running code from MainActivity
Right now Activity1 and Activity2 both launch at the same time. Is there a different way I should be writing/organizing my code? I guess I'm trying to do thing with Activities that I'm used to doing with methods. But I'm aware that my thinking might be wrong on this. I hope this makes sense.
Thank you for your help!
Your understanding of Activities is wrong. Activities do have methods that you can very well use.
An Activity is basically one screen that you see in your app. It can be started, stopped, resumed, etc. You can have different screens shown in one Activity (e. g. with Fragments).
If for example you have a list of notes in one Activity, you could have the detail of one note shown in another DetailActivity.
Only in rare cases, for example if you want to check on startup what Activity to show you could have another activity that does not have a layout but only does some checks and launches another one.
In each of your activities you can have methods to execute what you want on user interaction. Of course this can also go into other classes.
I would recommend you to start with a basic Android tutorial to gain a better understanding of the concepts.
For my current project, I will be using this SlidingUpPanel library.
The sliding up panel will host a fragment that will contain application/global level information. This panel will be in every activity in my application. This will be very similar to the way Google Play music works.
My question is, what is the best way to persist the sliding up panel fragment throughout my application? I see myself going about this in two ways...
Storing the fragment inside the Application class and loading it at the start of every activity (somehow, not even sure if this is a possibility).
Storing the data that it will display in the Application class & loading a new instance of the fragment, passing in the persisted data.
Which one of these two ways would be the best? Is 1. even possible? Are there any coding landmines with these approaches?
Storing a fragment to persist throughout the application lifecycle would be pretty unorthodox, mainly because the fragment class should be able to follow it's normal lifecycle events (in this case, mainly onPause and onResume) instead of being stuck somewhere in the application class.
It is definitely common practice to store the data and load it each time you display the fragment. If you want to enable some sort of cacheing or singleton pattern to access the data, it should most likely be with another object that the fragment can access but is not a member within the fragment.
There is a good video from google about leaking views and it touches briefly on the pitfalls of doing some similar to what you're proposing in bullet #1.
I think the structure of your app looks like it should be a single activity where that bar is in it, then the main content is a Fragment that you replace and use addToBackStack on in order to maintain the use of the back button. Otherwise, you are going to have a lot of repeated code with solution 2 (which means a lot of repeated work in the case of bugs etc., not very maintainable), or leak views using solution 1.
More info on providing a proper back implementation
I know many of you will direct me to the API. I am getting confused the more I read about Intent Fragment and Activity. Can anyone please describe what are these and why are these three important for the process of android application development?
Thanks for you help in advance.
1) Intent : -
It's an "intention" to do an action. It is like sending Message to Android OS to carry Out some task. For ex: Start other activity if some action happens. See Below Links :
http://developer.android.com/reference/android/content/Intent.html
2) Activity : -
It is a Single Screen that users Interacts with.It is the only component that can (and must) have a user interface. Learn Activity Life cycle. It is Very important. You Should declare your activity in manifest File.
3) Fragment : -
A Fragment is a behavior or a portion of user interface in an Activity. We can call it like sub Part of Activity.Just Remember that Fragment May or may not have view. It is Like Small Activity,but they can be multiple on single screens and we can interact with them. Read the Fragment Doc from Developers site. It is great place to Start. see this : - http://developer.android.com/guide/components/fragments.html
In Simple Words,
1) Activity: is a screen which hold view(s) for GUI components. A Window in Desktop Application. It has a lifecycle like created,paused, stopped like in window.
2) Fragment: is a component used for dynamic GUI development. it also has a own lifecycle. But only difference is that it can't be used directly. it should be encompassed in Activity in order work. An activity may have one or more than one fragments.
3) Intent: is a message passing framework from one activity to another. message can be anything causing an activity to resume, passing extra to an activity or cause an application to start.
I have been researching this for about an hour and cannot figure out whether to use fragments within an activity or start a new fragment activity.
Some sites make it sound as if you should have 1 activity and EVERYTHING else is a fragment. Is that the more proper way now? I can't figure out when you use an Activity (or fragment activity) and when you use a fragment.
I have an app for a conference with:
-Speakers (and sub views/activities/fragments) for each speaker.
-Schedule (different sections for each day)
-General info
-Sessions (different sections for each session).
So do I have 4 activities each with their own fragments or do I just use 1 activity with fragments and nested fragments?
You could do it either way, but generally it is best to use an Activity (or FragmentActivity) for each "screen".
If the user sees your app as logically a single screen that has little panels appearing/disappearing for different kinds of data, then use one activity with a lot of fragments. If the user sees it as "going to different screens", then you probably want multiple activities.
If you go with the one-activity-many-fragments model, you may find that your activity's code gets really complicated dealing with all the possible configurations of fragments. That is a good sign that you may want to split it into multiple Activities. Similarly, if you go with the many-activities model, but find that things get complicated as you pass shared data between activities, consider merging the activities.
Converting from Activity to FragmentActivity is as simple as changing the extends and nothing else needs changing.
My conclusions:
I stopped using Activity and only use FragmentActivity as it is more flexible and more up to date and backwards compatible (Using the support library).
If the FragmentActivity has a component that is large enough to be a standalone component, or needs to be one, then I make it as Fragment.
I haven't come across something that would require a complete separate activity to be within another activity, but that should only be used if that component is large enough and completely standalone enough to need an activity for itself.
I don't fully understand your app to be able to make a specific call on which you should use, if you want my opinion, can you provide more details on what you are working on and how are those components connected.
Regards
Another consideration in choosing a more decomposed architecture (many Activities) might be the cost of destruction / creation in the Activity Lifecycle. Do you plan to use Explicit/Implicit intents to leverage existing apps? More death. So, you might have only one activity in a dispatch oriented model and clearly see your apps logic in one place, but how much state will you have to save/restore? Are there performance penalties for re-inflating or populating data resources?
The Android Developer Guide states that activities are launched via Intents:
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
For Fragments, the usual way to display it on the screen is as follows:
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
Why is it that in one case I have to specify a class, and in the other an object? I.e., I would like to use something like
Activity nextActivity = new SignInActivity();
Intent intent = new Intent(this, nextActivity);
startActivity(intent);
Because Activity lifecycle is managed by Android whereas Fragment lifecycle is tied to the Activity in which it is contained.
As mentioned, Activity lifecycle is managed by Android. This is required, among other things, for Android to manage the system resources and also to take care of the back stack.
Fragment, on the other hand, was introduced to modularize and better organize the UI for devices with different sizes. According the the documentation:
Starting with HONEYCOMB, Activity implementations can make use of the
Fragment class to better modularize their code, build more
sophisticated user interfaces for larger screens, and help scale their
application between small and large screens.
To answer the latter part of your question, you can indeed pass the results of an activity to a second activity. But you should never create an instance of an Activity class for that. The right way is to use the startActivityForResult() and send the resulting value to the destination activity through the Intent.
While adding fragment, you are already specifying where exactly to insert that fragment into. So, the ideal way is to,
Create your fragment.
Insert into a layout of your current activity.
Use transactions to remove/manage your fragments, added to the current activity.
In no way, you could launch or use just a fragment, without attaching it to an existing activity.
Android handles Activity life cycle by itself. Just look at the methods of Activity class, they're just like a fill in the blanks. Android calls the shots here. Through these methods it just ask if you want to do something when this activity is created, resumed, paused etc.
The reasons for Android handling activity life cycle internally, are many:
Properly setting up an Activity involves lots of boiler plate code, better let system do it for you. The whole Context and window management is set up for you behind the scenes. Imagine the amount of extra work, if you had to do it for every Activity you created.
Activities are shared, home screen and other applications might want to launch/use them. How would be this possible if they have to call new MyActivity() of some obscure package ? . This is why Activities and other externally invokable components must be declared in application manifest.
Activities from many applications can be parts of an android task ( a piece of work from user's perspective). And are automatically placed/removed/re-arranged on a back-stack. Again, its better Android manage their creation and destruction rather than developers messing with this whole setup.
All user cares is that an Activity must show up when asked for, and just get out of the way if user navigates somewhere else. Android enforces this. Making an Activity appear on its own, or refuse to go away, just because its allowed to be programmed that way, is unacceptable.
Now Fragments , on the other hand are internal. They live inside an Activity and are not accessed from or shared with outside applications or tasks in any way. Fragments are even not a part of application manifest and hence are not exposed outside. Android need not worry about each fragment separately, because fragment life-cycle is bound to that of its parent Activity. Android doesn't care what you do with fragments internally, it can just end the activity and everything inside it is destroyed as well.