Idea: Constructors instead of Intents / Bundles?

#1

Hello,

I have an idea. How about a library / language feature so we can instantiate activities / fragments like this:

class SomeActivity
(
    val someArgument : Int
) : AppCompatActivity()
{
    val presenter = SomePresenter(this, someArgument)
}

Instead of:

class SomeActivity : AppCompatActivity()
{
    val someArgument : Int by lazy { intent.getIntExtra("x", 0) }
    val presenter by lazy { SomePresenter(this, someArgument) }
    companion object
    {
        fun start(context : Context)
        {
            val intent=Intent(context, SomeActivity::class.java)
            context.startActivity(intent)
        }
    }
}

Why?

Because intents are low level boilerplate… And avoids the most OOP-ish instantiation technique, the constructor.

Although there are libraries that generate Intent Builder classes (BundleArgs, AutoBundle, etc) all of them binds arguments as fields in the activity. Consider the following:

@BundleBuilder
class SomeActivity : AppCompatActivity()
{
    @Arg @JvmField
    var someArgument : Int = 0
    val presenter = SomePresenter(this)
    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)
        SomeActivityBundleBuilder.inject(this, intent)    
        presenter.someArgument=someArgument
    }
}

So we got field-level argument injection, but we still need to manually pass the argument to other objects via properties; or to lazy-load linked objects and pass arguments on constructors. Which is (imho) boilerplate code, compared to vanilla java-style “always pass by constructor” code.

Notes on my research about the topic

  1. You can override the default contructor of the activity, but you cannot use getIntent method in there because the intent is null. You can find the code where the android sdk instantiates an activity on android.app.Instrumentation.java (source code, lines 1180 and 1211). The activity is instantiated with reflection, using the default contructor. And then the intent is binded…

  2. You can create a fragment with a constructor with arguments (the classic java-style), but the recommended way is creating a bundle with the arguments, and binding this bundle to the fragment

#2

I’m also looking for a way to keep away from Intent, Intents everywhere make my code messy.
Single Activity with ViewModel might be a resolution.