From 95c97a0f1e2a2393cbdff503e1002d7cbddc09cc Mon Sep 17 00:00:00 2001 From: James Barr Date: Thu, 4 Mar 2021 11:25:55 -0800 Subject: [PATCH] Add CoreAppCompatActivity with delegate API (#407) --- .../libraries/rib-android-core/build.gradle | 54 +++++++++ .../rib-android-core/gradle.properties | 19 ++++ .../src/main/AndroidManifest.xml | 2 + .../com/uber/rib/core/ActivityDelegate.java | 58 ++++++++++ .../uber/rib/core/CoreAppCompatActivity.java | 106 ++++++++++++++++++ .../uber/rib/core/HasActivityDelegate.java | 27 +++++ .../src/test/resources/robolectric.properties | 1 + android/libraries/rib-android/build.gradle | 1 + .../java/com/uber/rib/core/RibActivity.java | 4 +- android/settings.gradle | 1 + 10 files changed, 270 insertions(+), 3 deletions(-) create mode 100644 android/libraries/rib-android-core/build.gradle create mode 100755 android/libraries/rib-android-core/gradle.properties create mode 100644 android/libraries/rib-android-core/src/main/AndroidManifest.xml create mode 100644 android/libraries/rib-android-core/src/main/java/com/uber/rib/core/ActivityDelegate.java create mode 100644 android/libraries/rib-android-core/src/main/java/com/uber/rib/core/CoreAppCompatActivity.java create mode 100644 android/libraries/rib-android-core/src/main/java/com/uber/rib/core/HasActivityDelegate.java create mode 100644 android/libraries/rib-android-core/src/test/resources/robolectric.properties diff --git a/android/libraries/rib-android-core/build.gradle b/android/libraries/rib-android-core/build.gradle new file mode 100644 index 000000000..7db3b1541 --- /dev/null +++ b/android/libraries/rib-android-core/build.gradle @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2017. Uber Technologies + * + * 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. + */ + +buildscript { + dependencies { + classpath deps.build.gradlePlugins.android + } +} + +apply plugin: 'com.android.library' + +android { + compileSdkVersion deps.build.compileSdkVersion + buildToolsVersion deps.build.buildToolsVersion + + defaultConfig { + minSdkVersion deps.build.minSdkVersion + targetSdkVersion deps.build.targetSdkVersion + } + + compileOptions { + sourceCompatibility deps.build.javaVersion + targetCompatibility deps.build.javaVersion + } + + testOptions { + unitTests { + includeAndroidResources = true + } + } +} + +dependencies { + implementation deps.apt.javaxInject + implementation deps.androidx.annotations + implementation deps.androidx.appcompat + testImplementation deps.external.roboelectricBase + testImplementation deps.androidx.appcompat +} + +apply from: rootProject.file('gradle/gradle-mvn-push.gradle') diff --git a/android/libraries/rib-android-core/gradle.properties b/android/libraries/rib-android-core/gradle.properties new file mode 100755 index 000000000..a5e264e55 --- /dev/null +++ b/android/libraries/rib-android-core/gradle.properties @@ -0,0 +1,19 @@ +# +# Copyright (C) 2017. Uber Technologies +# +# 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. +# + +POM_NAME=RIBs (Android Core) +POM_ARTIFACT_ID=rib-android-core +POM_PACKAGING=android diff --git a/android/libraries/rib-android-core/src/main/AndroidManifest.xml b/android/libraries/rib-android-core/src/main/AndroidManifest.xml new file mode 100644 index 000000000..598377718 --- /dev/null +++ b/android/libraries/rib-android-core/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/android/libraries/rib-android-core/src/main/java/com/uber/rib/core/ActivityDelegate.java b/android/libraries/rib-android-core/src/main/java/com/uber/rib/core/ActivityDelegate.java new file mode 100644 index 000000000..b1f6a9f3c --- /dev/null +++ b/android/libraries/rib-android-core/src/main/java/com/uber/rib/core/ActivityDelegate.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2017. Uber Technologies + * + * 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 com.uber.rib.core; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import androidx.annotation.IntRange; +import androidx.annotation.Nullable; + +/** + * This class represents a delegate which you can use to extend CoreAppCompatActivity's + * functionality. This allows RibActivity and any other type of Activity that you need to support to + * share CoreAppCompatActivity as a common parent. + */ +public interface ActivityDelegate { + /** @see {@link Activity#onCreate(Bundle) } */ + default void onCreate(@Nullable Bundle savedInstanceState) {} + + /** @see {@link Activity#onStart() } */ + default void onStart() {} + + /** @see {@link Activity#onResume() } */ + default void onResume() {} + + /** @see {@link Activity#onPause() } */ + default void onPause() {} + + /** @see {@link Activity#onStop() } */ + default void onStop() {} + + /** @see {@link Activity#onDestroy() } */ + default void onDestroy() {} + + /** @see {@link Activity#onActivityResult(Activity, int, int, Intent) } */ + default void onActivityResult( + Activity activity, int requestCode, int resultCode, @Nullable Intent data) {} + + /** @see {@link Activity#onRequestPermissionsResult(Activity, int, String[], int[]) } */ + default void onRequestPermissionsResult( + Activity activity, + @IntRange(from = 0, to = 255) int requestCode, + String[] permissions, + int[] grantResults) {} +} diff --git a/android/libraries/rib-android-core/src/main/java/com/uber/rib/core/CoreAppCompatActivity.java b/android/libraries/rib-android-core/src/main/java/com/uber/rib/core/CoreAppCompatActivity.java new file mode 100644 index 000000000..5e4380d00 --- /dev/null +++ b/android/libraries/rib-android-core/src/main/java/com/uber/rib/core/CoreAppCompatActivity.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2017. Uber Technologies + * + * 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 com.uber.rib.core; + +import android.content.Intent; +import android.os.Bundle; +import androidx.annotation.CallSuper; +import androidx.annotation.IntRange; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +/** Core Support v7 AppCompat Activity. */ +public abstract class CoreAppCompatActivity extends AppCompatActivity { + + @Nullable private ActivityDelegate activityDelegate; + + @CallSuper + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + if (getApplicationContext() instanceof HasActivityDelegate) { + activityDelegate = ((HasActivityDelegate) getApplicationContext()).activityDelegate(); + } + super.onCreate(savedInstanceState); + if (activityDelegate != null) { + activityDelegate.onCreate(savedInstanceState); + } + } + + @CallSuper + @Override + protected void onStart() { + super.onStart(); + if (activityDelegate != null) { + activityDelegate.onStart(); + } + } + + @CallSuper + @Override + protected void onResume() { + super.onResume(); + if (activityDelegate != null) { + activityDelegate.onResume(); + } + } + + @CallSuper + @Override + protected void onPause() { + if (activityDelegate != null) { + activityDelegate.onPause(); + } + super.onPause(); + } + + @CallSuper + @Override + protected void onStop() { + if (activityDelegate != null) { + activityDelegate.onStop(); + } + super.onStop(); + } + + @CallSuper + @Override + protected void onDestroy() { + if (activityDelegate != null) { + activityDelegate.onDestroy(); + activityDelegate = null; + } + super.onDestroy(); + } + + @CallSuper + @Override + public void onRequestPermissionsResult( + @IntRange(from = 0, to = 255) int requestCode, String[] permissions, int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (activityDelegate != null) { + activityDelegate.onRequestPermissionsResult(this, requestCode, permissions, grantResults); + } + } + + @CallSuper + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (activityDelegate != null) { + activityDelegate.onActivityResult(this, requestCode, resultCode, data); + } + } +} diff --git a/android/libraries/rib-android-core/src/main/java/com/uber/rib/core/HasActivityDelegate.java b/android/libraries/rib-android-core/src/main/java/com/uber/rib/core/HasActivityDelegate.java new file mode 100644 index 000000000..a27fdb630 --- /dev/null +++ b/android/libraries/rib-android-core/src/main/java/com/uber/rib/core/HasActivityDelegate.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017. Uber Technologies + * + * 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 com.uber.rib.core; + +/** Interface to indicate an object has a CoreAppCompatActivity.Delegate. */ +public interface HasActivityDelegate { + + /** + * Get the delegate. + * + * @return The delegate. + */ + ActivityDelegate activityDelegate(); +} diff --git a/android/libraries/rib-android-core/src/test/resources/robolectric.properties b/android/libraries/rib-android-core/src/test/resources/robolectric.properties new file mode 100644 index 000000000..a240a2bd7 --- /dev/null +++ b/android/libraries/rib-android-core/src/test/resources/robolectric.properties @@ -0,0 +1 @@ +constants=com.uber.rib.android.test.BuildConfig diff --git a/android/libraries/rib-android/build.gradle b/android/libraries/rib-android/build.gradle index a33a45c30..03542ef0f 100644 --- a/android/libraries/rib-android/build.gradle +++ b/android/libraries/rib-android/build.gradle @@ -44,6 +44,7 @@ android { } dependencies { + api project(":libraries:rib-android-core") api project(":libraries:rib-base") api deps.external.rxrelay2 api deps.external.rxjava2 diff --git a/android/libraries/rib-android/src/main/java/com/uber/rib/core/RibActivity.java b/android/libraries/rib-android/src/main/java/com/uber/rib/core/RibActivity.java index 49d216c41..4fbd0efa4 100644 --- a/android/libraries/rib-android/src/main/java/com/uber/rib/core/RibActivity.java +++ b/android/libraries/rib-android/src/main/java/com/uber/rib/core/RibActivity.java @@ -31,13 +31,11 @@ import com.uber.autodispose.lifecycle.LifecycleScopes; import com.uber.rib.core.lifecycle.ActivityCallbackEvent; import com.uber.rib.core.lifecycle.ActivityLifecycleEvent; - import io.reactivex.CompletableSource; import io.reactivex.Observable; -import androidx.appcompat.app.AppCompatActivity; /** Base implementation for all VIP {@link android.app.Activity}s. */ -public abstract class RibActivity extends AppCompatActivity +public abstract class RibActivity extends CoreAppCompatActivity implements ActivityStarter, LifecycleScopeProvider, RxActivityEvents { /** diff --git a/android/settings.gradle b/android/settings.gradle index 22fd39b44..aca53a2e7 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,5 +1,6 @@ include ':libraries:rib-test' include ':libraries:rib-android' +include ':libraries:rib-android-core' include ':libraries:rib-base' include ':libraries:rib-compiler-app' include ':libraries:rib-compiler-test'