Seeking a better pattern for constructing inherited fragments

satya - 11/3/2013 8:20:18 AM

Problem

Fragments are reborn and reconstructed by the android framework

this results in default constructors. Any initialization that was intended at original birth is accomplished through set arguments and rereading them during rebirth.

This makes it not so obvious to place restrictions on derived classes by their super classes as to what is the set of required arguments for a fragment to work.

satya - 11/3/2013 8:23:28 AM

One solution based on non-default constructors (it has a flaw)

  1. Provide both default and non-default constructors
  2. Have the super-most class register the bundle
  3. Most-important: Prevent any default constructor from inadvertently invoking the non-default constructor as that will do the setarguments at the wrong time

satya - 11/3/2013 8:35:51 AM

Almost works, but it has some flaws and assumptions

  1. You get an android compiler warning
  2. It depends on how the setArguments() is implemented on the fragment class. If it uses a replication on the bundle, it is too late for the derived classes to alter the bundle. This shifts the burden of registration to the derived classes and you cannot predict the future.
  3. The most derived class won't be able to supply its arguments in its default constructor and invoke the super classes non default constructor. this forces the derived class to call its constructor a different name (which is not possible) or invent an artificial argument to distinguish it from the default constructor.

satya - 11/3/2013 8:55:34 AM

Probably a better alternative is

  1. Rename your non-default constructors as init methods
  2. Have the derived class inits call base class inits to enforce constraints on what should be in the args bundle
  3. Those fragments that can be instantiated provide an explicit static newInstance() method
  4. Look with suspicion if there is a fragment that has a non default constructor (Only exception may be if it is an immediately derived class from a fragment and doesn't need to be further derived)
  5. Have the newInstance() method call typed init methods on the class that is being instantiated
  6. If you are further conscious of naming init methods the same, prefix them with class names

satya - 11/3/2013 8:56:13 AM

I will let you know if the later works in practice...as I am trying now

I will let you know if the later works in practice...as I am trying now

satya - 11/4/2013 9:10:42 AM

The semantics of setArguments may strongly argue with you to call it after the fragment is constructed...

Depending on the expectation of timing of when it is appropriate to call setArguments, you may be expected to call it after the entire object is constructed, and never as part of the construction, although it seem to work even when done as part of a non-default constructor