I was wondering if instead of having to create a new class for each activity is it possible to create mulitiple activities within one class?
So define various layout xml for various activities within one class, instead of having to create new classes for each activity.
Thanks
No, you should put each activity in seperate class. Take a look at this question. Someone is wondering just the same thing as you.
Ricky,
Yes, you may have multiple "Activities" defined inside a single class. But there are a lot of obstacles and issues with doing so. Before I answer this question, two things must be understood:
What you are asking goes against the Android guidelines for development, and those guidelines are enforced in as many ways as they can be during the compilation process, so nothing I say here is insured to work across any or all API versions of the Android SDK.
Different development environments do their own checks and compile in slightly different ways. I will be speaking from the Eclipse side of development.
Techniques listed here are for education, but introduce a lot of issues. For self education and theory, it is a wonderful practice to explore. However, the goal of this answer is to educate you as to why the guideline should be followed rather than sidestepped.
Requirements for an Activity
The first thing to understand is that Android has specific points that must be met for an Activity to be run. It must: a) be declared in the manifest; b) have an intent-filter describing how it is to be used; c) be a public class; d) be a top-level class.
Multiple Activities, Same Parent Class
This means that you may create an Activity inside of another class (an inner Activity, so to speak), but it must be declared static and public. This limits your Activity in a huge number of ways. Calls to methods or members that are instance-related (not static) to the parent class are not possible. So you lose a lot of time and code hacking around this.
Second, it affects your Android XML declaration for your Activity. This is where the real trouble comes in, because while it can be done, it is very specific and there is not any supporting documentation to make that happen. But that's okay, you wanted to know if you could make ONE class for your Activities.
Multiple Activities, Same Class
Well, Android determines which Activity to run based on its Intent. You could declare the same class multiple times, but with different Names and Intent-filters. If this is the case, then you would have to determine what to do based on the Intent and the extras included. This would be done in your onCreate() method.
Doing things in this manner would mean that you would have to code for two Activities in every place that you would normally deal with one. This would make it much harder to track down bugs to support your product. It would also make every routine operation take longer as you would have to decide which method to perform. For instance, if you overrode onDraw(), you would have to know which Activity you were drawing. Its ultimately just a big schmorgasborg (sp? does anyone know how to spell that word?) of "what do I do?!"
The Real Question
Why would you want to do this anyway?
1. If the answer is to save yourself time navigating your own project, believe me... That won't really happen. Your code will be harder to read, interpret and debug.
If the answer is that you want to save file space, I would reconsider your project's priorities.
If the answer is that you want to share functionality, consider extending Activity and then extending your new sub class. How do you think they made the ListActivity or TabActivity to begin with?
If you want to save state, you can place state in SharedPreferences or your Application object (if you have extended it).
As you can see, no matter your needs, there are many other ways to go about it in a way that doesn't cause you or anyone else a hassle.
Hope this helps,
FuzzicalLogic
Related
I want to make an application which embeds an activity in a tabbed UI from a number of applications. As far as I know it's officially disabled due to the security matter but probably some hacks exist!
I have heard of two ways:
converting the activity to a type of Fragment
using LocalActivityManager class which is currently deprecated.
I already tried both of them and failed due to lack of my ability. If there is something I missed or another approach, let me know!
Note that I can modify those because I have a source code of them.
I want to make an application which embeds an activity in a tabbed UI from a number of applications.
That is not possible.
As far as I know it's officially disabled due to the security matter but probably some hacks exist!
I doubt it.
I have heard of two ways
Neither of them are related to your problem as originally stated.
Note that I can modify those because I have a source code of them.
Then combine them into one application, creating one APK file. At that point, then you can start exploring converting UIs into fragments or otherwise combining things into a tabbed UI.
Many Android apps include a BaseActivity class of their own, which all Activities in the app extend. This is useful because it gives a central place to put functionality that's common across most/all activities. The main drawback of having a BaseActivity is you are then unable to use any of the Activity subclasses (ListActivity, etc.).
One alternative is to have an ActivityDelegate. This gives a central place for functionality while still allowing you to use Activity subclasses. It's also arguably more testable, since it uses composition instead of inheritance.
Both of these solutions potentially lead to a lot of spaghetti code when the BaseActivity/ActivityDelegate gets too large and convoluted. A possible solution to this is to use the delegate pattern, but split the functionality into many different Delegates. This reduces spaghetti code in the Delegates, but then the Activities get more complicated - they're now trying to forward their on* methods to lots of different Delegates instead of just one.
A possible solution to all of these problems is to use a Delegate Manager. The Delegate Manager keeps track of all the smaller Delegates in the app. Activities forward their on* methods to the Delegate Manager, which forwards them on to all of the individual Delegates. This accomplishes all of the following:
Dedupes code - all common functionality gets placed into one of the Delegates
Allows use of Activity subclasses
Simple code in all Activities - all on* methods are forwarded to just one class
Easily testable - it's simple to mock out everything around the Delegates and the Delegate Manager for unit tests
Has anyone tried using this pattern before? If so, how did it go?
As far as I understand, you're talking about one single DelegateManager object for the entire application. If this is the case, you can use registerActivityLifecycleCallbacks, see http://developer.android.com/reference/android/app/Application.html#registerActivityLifecycleCallbacks%28android.app.Application.ActivityLifecycleCallbacks%29
If you're on < API level 14 you need to take a look at: https://github.com/BoD/android-activitylifecyclecallbacks-compat.
registerActivityLifecycleCallbacks lets you hook into the activities onXXX lifecycle methods.
Doing this certainly has all the benefits you described:
decoupling being usable only when you actually need to repeat behavior which is kinda seldom for controller+view logic tied in together the way Activity works.
Removing inheritance is nice if you have activities you might reuse - but I've never had to do it before. But I guess a good use-case would be your home-cooked activity for handling settings or something like it that needs app-wide L&F & behavior.
On the top of my head I can think of these downsides:
Using listeners all over the place can blur path of the application activity/call hierarchy and can make the code hard to understand. This holds true for all listener/dispatcher type of programming. It's a powerful tool, but handle it with care.
It can introduce a lot of (as you mention) boilerplate/spaghetti code if all you do is pass on to lifecycle listeners/delegates.
it is your responsibility to de-register yourself from the Application with Application.unregisterActivityLifecycleCallbacks. I don't think there's a good way around it,
Personally I haven't used this design-pattern much for lifecycles, but it might be worthwhile for some use-cases. For example:
ApplicationLifecycleLogger: Every time you create/resume/pause... an activity, you logcat or something else making debugging lifecycles a tad bit easier.
If for example someone goes into an activity he/she is not allowed to go into due to model state of some sort (e.g. a ringing alarm -> can't go into AlarmEditActivity), you could do finish() there.
Passing object state across activity boundaries without Parcelable:s and screen rotation changes. Usually this is implemented with a Map in Application or some static field somewhere. You can do this by letting the delegators hold state.
Also, take a look at: Is there a design pattern to cut down on code duplication when subclassing Activities in Android?
I hope this was helpful =)
I'm currently attempting to convert my existing Android app to using Fragments. The main work that my activity does can sometimes take a while, so I implemented some Threads to act as callback handlers - I was led to believe this is best practice to use these and a progress dialog.
Hopefully that makes sense.
My question is: should I move those inner classes to my Fragment class, or keep them in my Activity class?
That depends how many fragments you have and what you're trying to do with those threads. While there is no general rule, here are two things to consider in making your decision.
(1) If you're doing something like downloading information that's going to be used in multiple fragments (say in a ViewPager or Tab set up) it might make sense to have the callbacks in your FragmentActivity this way you can easly distribute that information to the Fragment that will be handling the UI. Another example that comes to mind would be fetching location data. If the location data is going to be used throughout the app, and your FragmentActivity is hosting multiple fragments, it makes more sense to get the information in one place and simply update the fragments individually.
(2) If you're using something like AsyncTask for one-off downloads, posts, or other things unique to a specific fragment, there's nothing wrong with keeping it localized to that fragment. In fact, in that case, it would be less efficient to off load the task to your FragmentActivity than to complete the task localy.
Really there's not "right" answer. Just a question of how your app is structured and what you're trying to acomplish.
Actually the best practice for software in general is a little different, first of all you need to know that there's no "Hard Rules" to anything in software, the keyword is "All Depends(Taken from book Pragmatic Thinking and Learning)" and as such, it all depends on what you want and what you need, you should put things on a balance to know where is better for you, but going back to the best practice in general for these cases the best is to have a Business Model Class completely decoupled from either Fragment/Activity or any other android component, you are actually supposed to have a Model Class and together with a Controller Class, both of them should manipulate/populate the data and views within those elements...
Hope this helps.
Regards!
There's no hard and fast rule, but I like keep them in the scope within which they most naturally fit. If the result of a long running task is only useful within the fragment which initiated it then it lives in the fragment. If the task may affect multiple fragments then it might live in the activity.
My doubt here is how to achieve a clean and easy code to maintain over time in an Android app?, I'm trying to apply Uncle bob - clean code rules but as I keep going with development sometimes some rules must be broken, and I end with an Activity of 700 lines (I'm not using Fragment, and 700 lines seems to be a Class that "does too much things") so I want to know if someone has try an Android app with proper use of Fragment and could answer these questions:
1- does it really impact on Activity lines length (at least less than 300-500 [not strictly this numbers but a "reasonable" Class length] lines)?
2- does code keep clean and easy over the time?, not necessary with Uncle bob rules but considering best practice in OO while coding.
3- does it have a considerable impact in terms of "Performance"?
4- does Fragment help to support in a more simple way a wide fan of Screens?"
5- ignoring developer skills, what "should" be the way to go non-Fragment activities or activities with rich Fragment use?
Note: this is not an attemp of Duplication to Android - Activity vs FragmentActivity? since the topic here is not about tab format but best practice for android development.
sorry for my english ;).
You are conflating the use of fragments with the use of FragmentActivity.
FragmentActivity is a subclass of Activity designed for use with the backport of fragments from the Android Support package. You usually only use FragmentActivity if you are using the backport. If you are using fragments, but your android:minSdkVersion is set to 11 or higher, you can usually skip FragmentActivity.
With that in mind:
does it really impact on Activity lines length (at least less than 300 lines)?
That is impossible to say. It is equivalent to asking whether a Restaurant that subclasses Business will be longer or shorter than a Restaurant that subclasses FoodSupplier. It all depends on your code.
That being said, it is certainly possible that the use of fragments will reduce the lines of code in the activity. IMHO, that's not a good reason to use fragments.
does code keep clean and easy over the time?, not necessary with Uncle bob rules but considering best practice in OO while coding.
That is impossible to say. It is equivalent to asking whether a Restaurant that subclasses Business will be "clean and easy" compared to a Restaurant that subclasses FoodSupplier. It all depends on your code.
does it have a considerable impact in terms of "Performance"?
Not usually.
does Fragment help to support in a more simple way a wide fan of Screens?"
If by "wide fan of screens", you mean "a wide range of screen sizes", then yes, fragments can help with that. In fact, that's the #1 reason for using fragments, IMHO. However, fragments alone do not magically help with screen sizes, any more than having capital letters in method names magically helps with screen sizes.
ignoring developer skills, what "should" be the way to go FragmentActivity or Activity?
As stated previously, you usually only use FragmentActivity if you are using the backport of fragments. If you are using fragments, but your android:minSdkVersion is set to 11 or higher, you can usually skip FragmentActivity.
If your question really is "should I be using fragments in my app?", the answer is "probably, but it depends upon the app".
Yes, fragments are the way to go. They help spread your code around in a logical way so you don't have a 700 line activity, they keep your code easy because each fragment will have its own class usually, and they do, to answer your 4th question, make it easy to have "A wide fan of Screens".
I recommend this video to help get you started. For any beginners, this video is a great explanation of how to use fragments ( I know because I had a hard time figuring out how to use them until I watched this video). It is called "Programming Android with Fragments" by Andrew Ruffolo:
http://www.youtube.com/watch?v=KyXvq_kwfzg
This video demonstrates the power of fragments. You still need a main activity of some kind, but this main activity acts kind of like a container for the fragments, and most of the functionality of your app is handled by the fragments and their corresponding classes.
I have never used activities because I started app development after fragments were added to android, but it seems like fragments help break down your app in the same way that methods and inner classes help break down your classes, and the same way that classes help break down a project or program. I am not sure if this was possible or as simple using only activities before fragments were added.
I'm wanting to extend both a MapActivity and a FragmentActivity. I know Java doesn't allow multiple inheritance, so how do I do this? I've read something about a 'composite' type, but I've never implemented one so I don't know how to go about doing that.
Someone else HAS to have run into this before, how did you solve it?
EDIT: The reason I want this is because I have 3 activities in tabs; a map, an image gallery, and a settings list view. The code for all three of these "acitivities" is inside one big MapActivity called "Main". Yes I know this is ugly, and not good programming practice, and I don't remember why I wrote it this way. I think it was because I was reading most people recommended NOT having separate activities for separate tabs... which if I decided to split them into separate activities, I wouldn't have this problem anymore.
I have no idea why you would want such a thing, but I suppose the easiest solution is something like ActivityGroup, something similar to how TabbedActivity works.
I ended up solving this by going in and modifying the source of the Android support package and deploying my app with that. Outlined here, all I did was make FragmentActivity (android.support.v4.app) extend MapActivity. I don't think the reverse works... though maybe, and it would require you having the source of the mapping library you're using (in the case of Google Maps - no go)