Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the design logic behind Fragments as static inner classes vs standalone public classes?

I am not able to understand one important aspect of Android software design which I am just starting out with, from what I know Fragment design has been adopted in order to decouple the code, where the intuition is that the Activity remains as is and Fragment can be reused else where, maybe even in a different activity, or maybe along side other fragments, in something like a Master/Detail flow or landscape UI.

Okay so I have seen quite a handful of questions on SO asking as to why Fragments are placed as static inner classes within an Activity and the answer there is that if we do not make them static, the Fragment may hold a reference to the activity and something like a screen rotation or a re-draw might leak the activity or something.

This brings me back to square one and I have the question that, well, if the Fragment design has been adopted in order to decouple the code, then why are we marrying the Fragment to the Activity by putting it inside the activity class and not putting them as standalone public classes? Isn't that totally contradicting to the very existence of Fragments?

What is the down side of having a project structure as such? Where each Fragment is a separate class of its own? Given that my Fragment code can grow to like a 1000 lines especially when trying to do animations I am seeing this as far more neater, decoupled and reusable within activities other than it's intended parent Activity.

  • Do we still suffer from the memory leak issue mentioned above?
  • Am I missing something about the design logic? Please educate me.
  • Is there a way where the Fragments stay as an inner class and still be used elsewhere? I might be missing something here as well... so do inform me.

Project structure

Any other project design methods, concepts, corrections to my intuition are more than welcome since I am just starting out here, I would love to know all my options.

Thank you :)

like image 712
Abdullah Khan Avatar asked Mar 05 '14 07:03

Abdullah Khan


People also ask

What is the difference between an inner class and a static nested class?

A nested class is a member of its enclosing class. Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private. Static nested classes do not have access to other members of the enclosing class.

What is the purpose of static inner class in Java?

Java static nested class A static class is a class that is created inside a class, is called a static nested class in Java. It cannot access non-static data members and methods. It can be accessed by outer class name. It can access static data members of the outer class, including private.

What are the differences between static and non static nested classes?

A non-static nested class has full access to the members of the class within which it is nested. A static nested class does not have a reference to a nesting instance, so a static nested class cannot invoke non-static methods or access non-static fields of an instance of the class within which it is nested.

What are static inner classes?

A static inner class is a nested class which is a static member of the outer class. It can be accessed without instantiating the outer class, using other static members. Just like static members, a static nested class does not have access to the instance variables and methods of the outer class.


1 Answers

This brings me back to square one and I have the question that, well, if the Fragment design has been adopted in order to decouple the code, then why are we marrying the Fragment to the Activity by putting it inside the activity class and not putting them as standalone public classes? Isn't that totally contradicting to the very existence of Fragments?

The main driver for fragments isn't decoupling but rather composition: reusable pieces of user interface that can be easily composed together in different configurations. From composability follows modularity and from it decoupling so yes, decoupling is there but it's not the primary concern.

Read on about fragment design philosophy.

The modularity coin has another side: if two things belong together such as an activity and a fragment that is only used with that activity, they are best kept together and not spread out all over the codebase so they are easier to evolve together. A project structure like in your question where activities and fragments are in separate packages would not really follow this principle.

One commonly seen way to keep fragments in separate classes but close to related activities and such is to use a naming prefix so they sort together in alphabetical lists within the same package: e.g. FooActivity with FooDetailsFragment.

For simple fragments where there isn't that much code and the fragment is only used in one activity, it's perfectly fine to have them as static inner classes in that activity.

Just try to be consistent so other people reading the code can easily find their way around in the codebase and the WTFs/minute code metric is kept low.

Do we still suffer from the memory leak issue mentioned above?

No, the leak applies only to non-static inner classes that hold a reference to the outer class. Package-level classes do not have any outer class to held a reference to.

Since fragments share the hosting activity's lifecycle, leaking the outer object is not really the concern with fragments. It's just that the framework needs to be able to instantiate the fragments without any outer class objects, and static is a requirement for that.

Is there a way where the Fragments stay as an inner class and still be used elsewhere? I might be missing something here as well... so do inform me.

You can refer to public inner classes with the dot notation Outer.Inner in code or Outer$Inner with reflection (e.g. XML files).

While this is technically possible, doing so says you're relying on the internals of a class and that's a design smell. I'd really refer to inner classes in the outer class code itself.

like image 89
laalto Avatar answered Oct 09 '22 21:10

laalto