Fragment 2 fragment communicating - android

Why i should use the Communicating with Other Fragments pattern when I could simply use
((MyActivity)getActivity()).doFoo();
In my Fragment?

This is ultimately a question of coupling and re-usability.
If you use the code example you posted in your question your Fragment is not re-usable with other activities. It is 'tightly coupled'. It's fine if you're working on your own and you don't think anyone is likely to ever use or read your code later (including yourself), and that you're definitely never going to need to use that Fragment anywhere else. But generally speaking you should still use the proper pattern, just to get into the habit of using it.
If you have a position coding in a company keeping 'loose coupling' will help you and your co-workers a great deal in the long run, and means you can go straight back to your code and re-use it on later projects if called for.
Further reading.
Even further reading.
Even farther further reading.

Because it creates a strong direct coupling of your Fragment and your Activity, thus decreasing the re-usability of your Fragment : you can only use it with this Activity.
Using an interface to mediate the communication is more flexible has multiple activities can now embed your Fragment, they just have to implement the communication interface.
That's equivalent in term of program execution, but it's a better design, quite close from the Observable-Observer design pattern.
Also note that they are alternative solutions :
Otto
EventBus
RoboGuice events
Those solutions are even cleaner and will lead to more elegant code.

Communicating between fragments should be only through activity.
((MyActivity)getActivity()).doFoo() - will call a method in activity and then update the other fragment
Fragment should be control only by the activity. Say.. if an fragment has a direct way to communicate with the other fragment , then there are possible that an fragment can be detached from other fragment without the activity aware.

When you call ((MyActivity)getActivity()).doFoo() you are downcasting your object and you could encounter a RuntimeException if the containing Activity isn't a an instance of MyActivity. The direct call means that the Fragment is tightly coupled with the Activity. Many people believe this is not a good thing.
When you implement the interface as described in your link, you won't be able to build your app unless you're passing around an object that has implemented it.
This means that if you use the fragment elsewhere, you eradicate the risk of a RuntimeException because it is strongly typed.
There's a question here explaining why strong typing is good and tight coupling is bad

Related

Android: One ViewModel for multiple Fragments possible?

I have a general question about App architecture with Android. I am implementing an App (in Java) that has a single activity and 20Fragments (that are similar but not the same). So far I implemented everything in the fragments (UI, Logic, Database queries). Now I am considering to use a ViewModel but I am not sure whether it is worth the effort. So my question is whether each of my 20 Fragments should have an own ViewModel or whether I can just implement one ViewModel for all the 20 Fragments? Implementing a ViewModel for all Fragment classes would drastically increase the effort, so I would like to know if it is possible to have only one ViewModel for all Fragments?
It is technically possible to have one ViewModel for all Fragments.
However, since this one ViewModel would have to manage a number of very different use cases, it would be something like a god object. With 20 Fragments, it would have very many lines of code ...
Switching over to MVVM is generally worth the effort becasue in the long run the app is easier to test and to maintain.
It may be a good idea to have a BaseViewModel in your app: a ViewModel class which handles things which are similar in all use cases, like letting the Fragment know that it should show a loading indicator or an error message. The "normal" ViewModels could extend BaseViewModel and focus on their use cases.
It makes sense in some cases to have a shared ViewModel, for example when a Fragment shows a dialog with some EditTexts or when one has workflow with a sequence of 3-4 Fragments on a small device where on a larger device one or two Fragments would suffice.
Just in case, here's my favourite starting point for MVVM app architecture: Guide to app architecture
Have one view model for each fragment. This way each viewmodel is responsible for doing something related to one fragment and so testing is also easier.
In fact you can have multiple view models for a single fragments doing different things for you.
Keeping everything in one view model would make testing harder and also you have to keep viewmodel for all 20 fragments may be scoping to activity.
Now I am considering to use a ViewModel but I am not sure whether it
is worth the effor
This is definitely worth it if you want good for future development.
So my question is whether each of my 20 Fragments should have an own
ViewModel or whether I can just implement one ViewModel for all the 20
Fragments?
Each fragment should have its own ViewModel, I don't appreciate sharing ViewModel. I develop a lot of apps and what I've come to realize is that I should try to avoid tight coupling. Because every time you develop there will be a lot of changes and when you edit or add or remove it will make you edit a lot because the links are too tight. It would be nice to take them apart and still be able to run normally and when needed to be able to reassemble them like putting together puzzle pieces.
Implementing a ViewModel for all Fragment classes would drastically
increase the effort, so I would like to know if it is possible to have
only one ViewModel for all Fragments?
possible if you want, in programming nothing is impossible. But if you do, you shouldn't because it will only make your code more complicated.
You can read more about the model here.
https://developer.android.com/jetpack/guide#overview
You can go through with this link
Shareable ViewModel
This is pretty much easy with Kotlin by using extention function, But In Java, we need to create a function for creating ViewModel and handle their scope according to the lifecycle of activity/fragment.

Is it a bad practice to have multiple Viewmodels, approximately one for each fragment?

I have a project with 1 main activity and 4 fragments all inheriting from the same "BaseFragment".
When first started I managed the whole project with the same ViewModel all through the main activity and fragments but after a while, the code inside became too extensive and decided to split it in multiple ViewModels according to the necessities of each fragment/activity.
I created one "MainViewModel" and used it in the main activity and the rest of the ViewModels inherit from it.
My question is if it is a good practice for reducing the code in the ViewModel? is it perhaps inefficient to have multiple view models?
what other ways are preferred to simplify it?
Separation of concerns is almost never a bad thing. Ideally, each file/class should be responsible for one thing.
Additionally, you never know how the code will grow. Things tend to only get more complex over time, not usually simpler. So, while having multiple viewModels right now may feel like overkill, it will likely pay off later.
One case where a shared viewmodel between several fragments is ideal is when the fragments need to communicate with each other - they all would then use the activity viewmodel.
I would assume in this case you can use both approaches, though I have never done it, so I can't say for certain.

Is there any point of an Activity with one fragment?

All the reasons I can find for using Fragments in Android activities have to do with having the ability to display multiple classes/view in the same screen, encapsulating multiple logical components, etc.
Considering all this, it seems, fragments are only actually useful when you employ the use of many of them.
Is that so? Is there ever a point of using just one fragment in an activity?
I ask now because I saw an option on Android Studio to do just that, and I am wondering what the point is.
Out of my personal opinion, I would say yes.
For the following reasons:
Assuming you are familiar with Fragments, creating a Fragment is hardly any extra work plus has the following benefits
Fragments can easily be reused somewhere else (possibly another Activity that has more Fragments, furthermore, Fragments do not necessarily need to use up the full screen).
Activity transitions are more expensive, Fragment transitions are more sophisticated.
The Fragment animation framework is better (in terms of usability and performance).
I always like to keep the number of Activities to a minimum which keeps the AndroidManifest.xml short and clean.
UI separated into Fragments leads to cleaner code structure and easier code maintenance.
According to google coding guidelines, it is best practice to create as few Activities as possible, and create multiple Fragments instead that are switched inside an Activity.
Well it depends, if you are going to use that fragment in another activity yea, you have a "point" and maybe in a future you can reuse it on another activity, but in the case for example of a splash screen well, it don't have a point. All depend in the uses you want to give to your application.
Pros:
-> reusable piece of code
easy to utilize it again in any module
easy to debug
-> handles orientation changes better than activity using setRetainInstance(true)
-> great help when scale the app in future for multipane layouts or multi-screen support
Cons:
-> little overhead and time consuming if you are not familiar with fragments

Is having a Delegate Manager a good design idea?

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 =)

Is it best practice to put handler thread classes in the fragment or activity class?

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.

Categories

Resources