Skip to content

Commit

Permalink
[flutter_plugin_android_lifecycle] Stop reflecting (flutter#2467)
Browse files Browse the repository at this point in the history
The reflection was added to make the plugin compatible with previous
versions of Flutter. Now that the latest stable has updated we can
update the code to be safer and avoid potential issues with code
shrinking in release builds.

Also removes a Gradle workaround that was only required for pre 1.12
versions of Flutter.
  • Loading branch information
Michael Klimushyn authored Jan 14, 2020
1 parent a9f97e8 commit 8db13f1
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 70 deletions.
5 changes: 5 additions & 0 deletions packages/flutter_plugin_android_lifecycle/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 1.0.4

* Require Flutter SDK 1.12.13 or greater.
* Change to avoid reflection.

## 1.0.3

* Remove the deprecated `author:` field from pubspec.yaml
Expand Down
27 changes: 4 additions & 23 deletions packages/flutter_plugin_android_lifecycle/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,27 +37,8 @@ android {
}
}

// TODO(amirh): Remove this hack once androidx.lifecycle is included on stable. https://github.com/flutter/flutter/issues/42348
afterEvaluate {
def containsEmbeddingDependencies = false
for (def configuration : configurations.all) {
for (def dependency : configuration.dependencies) {
if (dependency.group == 'io.flutter' &&
dependency.name.startsWith('flutter_embedding') &&
dependency.isTransitive())
{
containsEmbeddingDependencies = true
break
}
}
}
if (!containsEmbeddingDependencies) {
android {
dependencies {
def lifecycle_version = "2.1.0"
api "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
api "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
}
}
}
dependencies {
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:1.10.19'
}

Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,8 @@
package io.flutter.embedding.engine.plugins.lifecycle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.Lifecycle;
import io.flutter.Log;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/** Provides a static method for extracting lifecycle objects from Flutter plugin bindings. */
public class FlutterLifecycleAdapter {
Expand All @@ -22,48 +18,11 @@ public class FlutterLifecycleAdapter {
* <p>Returns null if the Flutter engine version does not include the lifecycle extraction code.
* (this probably means the Flutter engine version is too old).
*/
@Nullable
@NonNull
public static Lifecycle getActivityLifecycle(
@NonNull ActivityPluginBinding activityPluginBinding) {
try {
Method getLifecycle = ActivityPluginBinding.class.getMethod("getLifecycle");
Object hiddenLifecycle = getLifecycle.invoke(activityPluginBinding);
return getHiddenLifecycle(hiddenLifecycle);
} catch (ClassNotFoundException
| NoSuchMethodException
| IllegalAccessException
| InvocationTargetException e) {
Log.w(
TAG,
"You are attempting to use Flutter plugins that are newer than your"
+ " version of Flutter. Plugins may not work as expected.");
}
return null;
}

// TODO(amirh): add a getter for a Service lifecycle.
// https://github.com/flutter/flutter/issues/43741

/**
* Returns the lifecycle object for the given Flutter plugin binding.
*
* <p>Returns null if the Flutter engine version does not include the lifecycle extraction code.
* (this probably means the Flutter engine version is too old).
*/
@NonNull
private static Lifecycle getHiddenLifecycle(@NonNull Object reference)
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException,
ClassNotFoundException {
Class hiddenLifecycleClass =
Class.forName("io.flutter.embedding.engine.plugins.lifecycle.HiddenLifecycleReference");

if (!reference.getClass().equals(hiddenLifecycleClass)) {
throw new IllegalArgumentException(
"The reference argument must be of type HiddenLifecycleReference. Was actually "
+ reference);
}

Method getLifecycle = reference.getClass().getMethod("getLifecycle");
return (Lifecycle) getLifecycle.invoke(reference);
HiddenLifecycleReference reference =
(HiddenLifecycleReference) activityPluginBinding.getLifecycle();
return reference.getLifecycle();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package io.flutter.embedding.engine.plugins.lifecycle;

import static org.junit.Assert.assertEquals;

import android.app.Activity;
import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.PluginRegistry;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

public class FlutterLifecycleAdapterTest {
@Mock Lifecycle lifecycle;

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}

@Test
public void getActivityLifecycle() {
TestActivityPluginBinding binding = new TestActivityPluginBinding(lifecycle);

Lifecycle parsedLifecycle = FlutterLifecycleAdapter.getActivityLifecycle(binding);

assertEquals(lifecycle, parsedLifecycle);
}

private static final class TestActivityPluginBinding implements ActivityPluginBinding {
private final Lifecycle lifecycle;

TestActivityPluginBinding(Lifecycle lifecycle) {
this.lifecycle = lifecycle;
}

@NonNull
public Object getLifecycle() {
return new HiddenLifecycleReference(lifecycle);
}

@Override
public Activity getActivity() {
return null;
}

@Override
public void addRequestPermissionsResultListener(
@NonNull PluginRegistry.RequestPermissionsResultListener listener) {}

@Override
public void removeRequestPermissionsResultListener(
@NonNull PluginRegistry.RequestPermissionsResultListener listener) {}

@Override
public void addActivityResultListener(
@NonNull PluginRegistry.ActivityResultListener listener) {}

@Override
public void removeActivityResultListener(
@NonNull PluginRegistry.ActivityResultListener listener) {}

@Override
public void addOnNewIntentListener(@NonNull PluginRegistry.NewIntentListener listener) {}

@Override
public void removeOnNewIntentListener(@NonNull PluginRegistry.NewIntentListener listener) {}

@Override
public void addOnUserLeaveHintListener(
@NonNull PluginRegistry.UserLeaveHintListener listener) {}

@Override
public void removeOnUserLeaveHintListener(
@NonNull PluginRegistry.UserLeaveHintListener listener) {}

@Override
public void addOnSaveStateListener(
@NonNull ActivityPluginBinding.OnSaveInstanceStateListener listener) {}

@Override
public void removeOnSaveStateListener(
@NonNull ActivityPluginBinding.OnSaveInstanceStateListener listener) {}
}
}
4 changes: 2 additions & 2 deletions packages/flutter_plugin_android_lifecycle/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name: flutter_plugin_android_lifecycle
description: Flutter plugin for accessing an Android Lifecycle within other plugins.
version: 1.0.3
version: 1.0.4
homepage: https://github.com/flutter/plugins/tree/master/packages/flutter_plugin_android_lifecycle

environment:
sdk: ">=2.1.0 <3.0.0"
flutter: ">=1.10.0 <2.0.0"
flutter: ">=1.12.13 <2.0.0"

dependencies:
flutter:
Expand Down

0 comments on commit 8db13f1

Please sign in to comment.