Intents are an integral part of any app. Thanks to Kotlin, we can now simplify the way we can use them. All driven by Extension Functions. We touched on this back in my post about Extending Resources.

Starting an Activity

Let’s start with the most common case. If we are inside a Context such an Activity , we can start another one in java.

Intent intent = new Intent(this, NextActivity.class);

startActivity(intent);

Using Extensions, we can come to something a bit more readable.

startActivity {

component = componentFor(HomeActivity::class)

}

The higher-order function startActivity takes a lambda which is applied to a new Intent and then calls the original startActivity(Intent) .

fun Context.startActivity(f: Intent.() -> Unit): Unit =

Intent().apply(f).run(this::startActivity)

The other part of this solution, componentFor , adds a factory method to the Context . Using the provided Class to create a ComponentName .

fun Context.componentFor(targetType: KClass<*>) =

componentFor(targetType.java)

fun Context.componentFor(targetType: Class<*>) =

ComponentName(this, targetType)

The constructor we used earlier with Java, internally, applies the component name to the Intent .

public Intent(Context packageContext, Class<?> cls) {

mComponent = new ComponentName(packageContext, cls);

}

We are doing the same with startActivity . however, we can simplify this further by adding an inline helper for this:

inline fun <reified T: Activity> Context.start(

noinline f: Intent.() -> Unit = {}

) = startActivity {

component = componentFor(T::class.java)

f(this)

}

Now we can start our activity just by mentioning it.

start<HomeActivity>()

We also get type safety and only allow Activity types, avoiding the embarrassment of trying to start a service like this. We can still use the lambda parameter to add more configuration.

start<HomeActivity> {

categories += CATEGORY_INFO

}

If we want to start the activity with an action instead of a type it can be done too