-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Add plugin for Android lifecycle in embedding #2168
Conversation
| import java.lang.reflect.InvocationTargetException; | ||
| import java.lang.reflect.Method; | ||
|
|
||
| public class FlutterLifecycleAdapter { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Needs documentation.
https://google.github.io/styleguide/javaguide.html#s7.3-javadoc-where-required
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a nit, but this is still needed for this class to comply with Google Java style.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
...oid/app/src/main/java/io/flutter/plugins/flutter_android_lifecycle_example/MainActivity.java
Show resolved
Hide resolved
packages/flutter_android_lifecycle/lib/flutter_android_lifecycle.dart
Outdated
Show resolved
Hide resolved
...oid/src/main/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapter.java
Show resolved
Hide resolved
mklim
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Just a couple minor nits still.
| import java.lang.reflect.InvocationTargetException; | ||
| import java.lang.reflect.Method; | ||
|
|
||
| public class FlutterLifecycleAdapter { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a nit, but this is still needed for this class to comply with Google Java style.
...oid/app/src/main/java/io/flutter/plugins/flutter_android_lifecycle_example/MainActivity.java
Show resolved
Hide resolved
| in the plugin's binding. | ||
|
|
||
| The purpose of having this plugin instead of exposing an Android `Lifecycle` object in the engine's | ||
| Android embedder plugins API is to force plugins to have a pub constraint that signifies the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, the term "embedder" refers to the C++ code. "Embedding" is the name given to the Java/Obj-C layers.
https://github.com/flutter/flutter/wiki/Glossary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
|
||
| @Nullable private Lifecycle lifecycle = null; | ||
|
|
||
| public FlutterLifecycleAdapter(@NonNull Object reference) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently the usage of this API looks like:
FlutterLifecycleAdapter adapter =
new FlutterLifecycleAdapter(flutterPluginBinding.getLifecycle());
Lifecycle lifecycle = adapter.getLifecycle();What do you think about making the getLifecycle method static instead, I see how usually we want to avoid static methods for testability, but in this case I don't see how this is particularly useful especially without us adding some FlutterLifecycleAdapterFactory method which will potentially allow tests to replace the concrete implementation of FlutterLifecycleAdapter.
Second question - what do yo think about making the adapter be the one that calls getLifecycle?
If we do both of these we may end up with the call site looking like:
Lifecycle lifecycle = FlutterLifecycleAdapter.getLifecycle(flutterPluginBinding);What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I avoid any static call that I don't absolutely need, but it's up to you. Seems like you can also achieve the second goal whether you go static or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I avoid any static call that I don't absolutely need, but it's up to you.
I'm looking for feedback 😄 do you see any issue with using static here?
Seems like you can also achieve the second goal whether you go static or not.
Yes, that's why I separated them to discuss separately, what is your opinion on that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the second suggestion is fine.
My feedback on the static suggestion is that I never make something static if I don't have to. I would personally not make it static. But I'm also not going to block this PR if you choose to do so. I don't see anything that will break by making it static. Then again, I could say the same thing for many instance methods that aren't static.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is totally subjective so I think it's up to you.
My personal opinion on static is that it's preferable if the method is truly immutable, doesn't require any kind of state or precondition, and truly doesn't have any kind of side effects. Using static in that way is a soft indicator that a method is purely functional. Good examples are Arrays#asList or TextUtils#isEmpty. A "bad" counter example of static is our own FlutterJNI, which has a bunch of "static" methods that don't depend on any member variables but do depend on there being this magic global c library loaded in the program's global runtime. The danger in methods like that is first that it's extremely easy to call them out of sync, and then second that they're really hard to work around when testing.
The generic problem with any static method is that it can't be mocked in unit tests. I generally prefer testing real behavior to using mocks whenever possible so that's not a huge concern to me but it can be a gigantic headache in the moment when the method really does need to be avoided in a test context (again, like FlutterJNI). Static also prevents subclasses from overriding the method, but that's a non-issue for me because I generally prefer composition to inheritance.
I think in this specific case it would be fine to make this static, because it's basically just returning the object that's passed into it. In a test context if you really needed to mock anything you would be returning a mock from the input parameter. I again prefer static interfaces because they're a soft signal that the function doesn't have silent side effects so I'd be happy to use one here, but it's totally subjective.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated to static, I think there's an upside (less cluttered call site) and no downside.
|
Will land on green |
|
Actually I'll wait for another LGTM from @matthew-carroll and @mklim as the public API changed |
|
LGTM |
mklim
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This plugin just landed in: #2168 The flutter_android_lifecycle package name is already taken, renaming to flutter_plugin_android_lifecycle.
…r#2205) This plugin just landed in: flutter#2168 The flutter_android_lifecycle package name is already taken, renaming to flutter_plugin_android_lifecycle.
…r#2205) This plugin just landed in: flutter#2168 The flutter_android_lifecycle package name is already taken, renaming to flutter_plugin_android_lifecycle.
Based off @matthew-carroll's #2129
Changes in this PR:
Original description
Add plugin for Android lifecycle in embedding.
Embedding side:
flutter/engine#12715