diff --git a/api/current.txt b/api/current.txt index e805fde9..cc3fa878 100644 --- a/api/current.txt +++ b/api/current.txt @@ -1,3 +1,11 @@ +package androidx.core.activity { + + public final class ActivityKt { + ctor public ActivityKt(); + } + +} + package androidx.core.animation { public final class AnimatorKt { diff --git a/src/androidTest/AndroidManifest.xml b/src/androidTest/AndroidManifest.xml index 6f5cb7ec..907fe7fd 100644 --- a/src/androidTest/AndroidManifest.xml +++ b/src/androidTest/AndroidManifest.xml @@ -3,5 +3,6 @@ + diff --git a/src/androidTest/java/androidx/core/TextExtraActivity.kt b/src/androidTest/java/androidx/core/TextExtraActivity.kt new file mode 100644 index 00000000..8231790d --- /dev/null +++ b/src/androidTest/java/androidx/core/TextExtraActivity.kt @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.core + +import android.app.Activity +import androidx.core.activity.extra + +class TextExtraActivity : Activity() { + + val stringExtra by extra(EXTRA_STRING) + val intExtra by extra(EXTRA_INT) + val nullableIntExtra by extra(EXTRA_NULLABLE_INT) + val intDefaultExtra by extra(EXTRA_INT_DEFAULT) { DEFAULT_INT } + val nullableIntDefaultExtra by extra(EXTRA_NULLABLE_INT_DEFAULT) { DEFAULT_NULLABLE_INT } + + companion object { + const val EXTRA_STRING = "string" + const val EXTRA_INT = "int" + const val EXTRA_NULLABLE_INT = "nullable_int" + const val EXTRA_INT_DEFAULT = "int_default" + const val EXTRA_NULLABLE_INT_DEFAULT = "nullable_int_default" + + const val DEFAULT_INT: Int = 42 + val DEFAULT_NULLABLE_INT: Int? = null + } +} \ No newline at end of file diff --git a/src/androidTest/java/androidx/core/activity/ActivityTest.kt b/src/androidTest/java/androidx/core/activity/ActivityTest.kt new file mode 100644 index 00000000..77906c8e --- /dev/null +++ b/src/androidTest/java/androidx/core/activity/ActivityTest.kt @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.core.activity + +import android.content.Intent +import android.os.Bundle +import android.support.test.rule.ActivityTestRule +import androidx.core.TextExtraActivity +import androidx.testutils.assertThrows +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull +import org.junit.Rule +import org.junit.Test + +class ActivityTest { + + @JvmField + @Rule + val rule = ActivityTestRule(TextExtraActivity::class.java, false, false) + + @Test + fun get() { + val activity = launchExtraActivity { + putExtra(TextExtraActivity.EXTRA_STRING, "test") + putExtra(TextExtraActivity.EXTRA_INT, 1) + putExtra(TextExtraActivity.EXTRA_NULLABLE_INT, 2) + putExtra(TextExtraActivity.EXTRA_INT_DEFAULT, 3) + putExtra(TextExtraActivity.EXTRA_NULLABLE_INT_DEFAULT, 4) + } + assertEquals("test", activity.stringExtra) + assertEquals(1, activity.intExtra) + assertEquals(2, activity.nullableIntExtra) + assertEquals(3, activity.intDefaultExtra) + assertEquals(4, activity.nullableIntDefaultExtra) + } + + @Test + fun getMissing() { + val activity = launchExtraActivity() + assertThrows { activity.stringExtra } + assertThrows { activity.intExtra } + assertNull(activity.nullableIntExtra) + assertEquals(TextExtraActivity.DEFAULT_INT, activity.intDefaultExtra) + assertEquals(TextExtraActivity.DEFAULT_NULLABLE_INT, activity.nullableIntDefaultExtra) + } + + @Test + fun getNull() { + val activity = launchExtraActivity { + putExtra(TextExtraActivity.EXTRA_STRING, null as String?) + putExtra(TextExtraActivity.EXTRA_INT, null as Int?) + putExtra(TextExtraActivity.EXTRA_NULLABLE_INT, null as Int?) + putExtra(TextExtraActivity.EXTRA_INT_DEFAULT, null as Int?) + putExtra(TextExtraActivity.EXTRA_NULLABLE_INT_DEFAULT, null as Int?) + } + assertThrows { activity.stringExtra } + assertThrows { activity.intExtra } + assertNull(activity.nullableIntExtra) + assertEquals(TextExtraActivity.DEFAULT_INT, activity.intDefaultExtra) + assertEquals(TextExtraActivity.DEFAULT_NULLABLE_INT, activity.nullableIntDefaultExtra) + } + + @Test + fun getWrongType() { + val activity = launchExtraActivity { + putExtra(TextExtraActivity.EXTRA_STRING, Bundle()) + putExtra(TextExtraActivity.EXTRA_INT, Bundle()) + putExtra(TextExtraActivity.EXTRA_NULLABLE_INT, Bundle()) + putExtra(TextExtraActivity.EXTRA_INT_DEFAULT, Bundle()) + putExtra(TextExtraActivity.EXTRA_NULLABLE_INT_DEFAULT, Bundle()) + } + assertThrows { activity.stringExtra } + assertThrows { activity.intExtra } + assertThrows { activity.nullableIntExtra } + assertEquals(TextExtraActivity.DEFAULT_INT, activity.intDefaultExtra) + assertEquals(TextExtraActivity.DEFAULT_NULLABLE_INT, activity.nullableIntDefaultExtra) + } + + private fun launchExtraActivity(configure: Intent.() -> Unit = {}): TextExtraActivity { + val intent = Intent().apply(configure) + return rule.launchActivity(intent) + } +} diff --git a/src/main/java/androidx/core/activity/Activity.kt b/src/main/java/androidx/core/activity/Activity.kt new file mode 100644 index 00000000..d9c9eb9a --- /dev/null +++ b/src/main/java/androidx/core/activity/Activity.kt @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.core.activity + +import android.app.Activity + +/** + * Returns a [Lazy] instance that parses the receiver's input intent and extracts an extra from type + * [T] mapped by the input [key]. + * + * The returned value can be used as a property delegate, for instance: + * + * ```kotlin + * class MyActivity : Activity() { + * + * private val name by extra("name") + * } + * ``` + * + * If such value can't be retrieved, an exception will be thrown. This will happen when: + * + * - There is an extra mapped by [key] and it can't be cast to [T] + * - There's no extra mapped by [key] and [T] is not a nullable type + * + * @param key The extra key + * @param T The extra type + * @return A [Lazy] that returns an intent extra + */ +inline fun Activity.extra(key: String): Lazy = lazy { + val value = intent.extras?.get(key) + if (value is T) { + value + } else { + throw IllegalArgumentException("Couldn't find extra with key \"$key\" from type " + + T::class.java.canonicalName) + } +} + +/** + * Returns a [Lazy] instance that parses the receiver's input intent and extracts an extra from type + * [T] mapped by the input [key], returning the result of the [default] function in case the extra + * can't be extracted. + * + * The returned value can be used as a property delegate, for instance: + * + * ```kotlin + * class MyActivity : Activity() { + * + * private val name by extra("name") { "Default name" } + * } + * ``` + * + * If such value can't be retrieved, the result from [default] will be returned. This will happen + * when: + * + * - There is an extra mapped by [key] and it can't be cast to [T] + * - There's no extra mapped by [key] and [T] is not a nullable type + * + * @param key The extra key + * @param default A function that returns the default value + * @param T The extra type + * @return A [Lazy] that returns an intent extra + */ +inline fun Activity.extra(key: String, crossinline default: () -> T): Lazy = lazy { + val value = intent.extras?.get(key) + if (value is T) value else default() +} \ No newline at end of file