Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Conversation

@amirh
Copy link
Contributor

@amirh amirh commented Oct 8, 2019

Based off @matthew-carroll's #2129

Changes in this PR:

  • Change the iOS plugin to ObjC.
  • Add e2e tests.
  • Don't crash the sample app if the lifecycle API isn't available (so it passes on master)
  • Cleanup unneeded files.

Original description

Add plugin for Android lifecycle in embedding.

Embedding side:
flutter/engine#12715

@mklim mklim self-assigned this Oct 8, 2019
@mklim mklim self-requested a review October 8, 2019 22:54
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class FlutterLifecycleAdapter {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Contributor

@mklim mklim left a 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 {
Copy link
Contributor

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.

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
Copy link
Contributor

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

Copy link
Contributor Author

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) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mklim @matthew-carroll

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?

Copy link
Contributor

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.

Copy link
Contributor Author

@amirh amirh Oct 16, 2019

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?

Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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.

@amirh
Copy link
Contributor Author

amirh commented Oct 16, 2019

Will land on green

@amirh
Copy link
Contributor Author

amirh commented Oct 16, 2019

Actually I'll wait for another LGTM from @matthew-carroll and @mklim as the public API changed

@matthew-carroll
Copy link
Contributor

LGTM

Copy link
Contributor

@mklim mklim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@amirh amirh merged commit 8251326 into flutter:master Oct 16, 2019
amirh added a commit that referenced this pull request Oct 17, 2019
This plugin just landed in: #2168

The flutter_android_lifecycle package name is already taken, renaming to flutter_plugin_android_lifecycle.
mormih pushed a commit to mormih/plugins that referenced this pull request Nov 17, 2019
mormih pushed a commit to mormih/plugins that referenced this pull request Nov 17, 2019
…r#2205)

This plugin just landed in: flutter#2168

The flutter_android_lifecycle package name is already taken, renaming to flutter_plugin_android_lifecycle.
sungmin-park pushed a commit to sungmin-park/flutter-plugins that referenced this pull request Dec 17, 2019
sungmin-park pushed a commit to sungmin-park/flutter-plugins that referenced this pull request Dec 17, 2019
…r#2205)

This plugin just landed in: flutter#2168

The flutter_android_lifecycle package name is already taken, renaming to flutter_plugin_android_lifecycle.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants