Last active
August 1, 2019 07:44
-
-
Save ZakTaccardi/ca8bdbbc48d724f47d596072fb4b68d1 to your computer and use it in GitHub Desktop.
A better way to launch activities. Companion code to https://medium.com/@ZakTaccardi/a-better-way-to-launch-activities-8a1045181b16
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@file:Suppress("unused", "FunctionName", "IllegalIdentifier") | |
import android.annotation.SuppressLint | |
import android.app.Activity | |
import android.content.Context | |
import android.content.Intent | |
import android.os.Bundle | |
/** | |
* The best way to launch yourself an activity. Your implementation should enable the following api: | |
* | |
* ```kotlin | |
* YourActivityArgs(param1, param2) | |
+ .launch(activityContext); | |
* ``` | |
* | |
* Your deserialization (from an intent) could look like: | |
* | |
* ```kotlin | |
* YourActivityArgs.of(intent) | |
* ``` | |
*/ | |
interface ActivityArgs { | |
/** | |
* @return returns an intent that can be used to launch this activity. | |
*/ | |
fun intent(activity: Context): Intent | |
/** | |
* Launches the activity given your activity context. | |
* | |
* The default implementation uses the intent generated from [intent] | |
*/ | |
fun launch(activity: Context) = activity.startActivity(intent(activity)) | |
} | |
@SuppressLint("Registered") | |
class MediumProfileActivity : Activity() { | |
private val args by lazy { | |
MediumProfileActivityArgs.deserializeFrom(intent) | |
} | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
// easily reference` your activity's arguments! | |
args.name | |
args.shortBio | |
args.profilePhotoUrl | |
} | |
} | |
/** | |
* Arguments to launch [MediumProfileActivity] | |
*/ | |
data class MediumProfileActivityArgs( | |
val name: String, | |
val shortBio: String, | |
val profilePhotoUrl: String | |
) : ActivityArgs { | |
override fun intent(activity: Context): Intent = Intent( | |
activity, MediumProfileActivity::class.java | |
).apply { | |
putExtra(NAME_KEY, name) | |
putExtra(SHORT_BIO_KEY, shortBio) | |
putExtra(PROFILE_PHOTO_URL_KEY, profilePhotoUrl) | |
} | |
companion object { | |
fun deserializeFrom(intent: Intent): MediumProfileActivityArgs { | |
return MediumProfileActivityArgs( | |
name = intent.getStringExtra(NAME_KEY), | |
shortBio = intent.getStringExtra(SHORT_BIO_KEY), | |
profilePhotoUrl = intent.getStringExtra(PROFILE_PHOTO_URL_KEY) | |
) | |
} | |
} | |
} | |
private const val NAME_KEY = "name_key" | |
private const val SHORT_BIO_KEY = "short_bio_key" | |
private const val PROFILE_PHOTO_URL_KEY = "profile_photo_url_key" | |
@SuppressLint("Registered") | |
class SomeOtherActivity : Activity() { | |
fun goToMediumProfile() { | |
val currentActivity = this | |
MediumProfileActivityArgs( | |
"Zak Taccardi", | |
"Eat. Sleep. Android.", | |
"www.profile.com/ZakTaccardi.png" | |
) | |
.launch(currentActivity) | |
} | |
} | |
@Test | |
fun `test args serialization and de-serialization`() { | |
val expectedArgs = MediumProfileActivityArgs( | |
"Zak Taccardi", | |
"Eat. Sleep. Android.", | |
"www.profile.com/ZakTaccardi.png" | |
) | |
// serialize args to intent | |
val serializedIntent = expectedArgs.intent(context) | |
// deserialize intent into args instance | |
val actualArgs = MediumProfileActivityArgs.deserializeFrom(serializedIntent) | |
// verify de-serialized args are equal to original args | |
Assertions.assertThat(actualArgs) | |
.isEqualTo(expectedArgs) | |
} | |
// the below serves to avoid red compilation errors above | |
annotation class Test | |
class Assertions { | |
companion object { | |
fun assertThat(actualArgs: MediumProfileActivityArgs) = AssertionHelper | |
object AssertionHelper { | |
fun isEqualTo(expected: MediumProfileActivityArgs) {} | |
} | |
} | |
} | |
@SuppressLint("StaticFieldLeak") | |
val context: Context = null!! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Well written ! 👍
In case anyone looking for
startActivityForResult
:fun launchActivityForResult(activity: Activity,requestCode : Int) = activity.startActivityForResult(intent(activity),requestCode)