Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use PlatformViewLink widget for Android WebView #462

Conversation

plateaukao
Copy link
Contributor

@plateaukao plateaukao commented Jul 27, 2020

Connection with issue(s)

Resolve issue: flutter/flutter#41089

[webview_flutter] Keyboard language can't change on Android (flutter/flutter#41089) is listed in issue (flutter/flutter#61133) and it's fixed by flutter PR: flutter/plugins#2883

Although this issue is reported to webview_flutter, it happens in flutter_inappwebview too, and especially for users who use google gboard as input method, and try to switch to Chinese input methods.

So, I ported the fix from webview_flutter plugin.

Testing and Review Notes

Steps:

  • You have to change flutter channel to dev in order to build this PR, since the so-called hybrid composition is now only available for flutter v1.20 or v1.21.
  • Install Google gboard input method, and install chinese pinyin or chuyin input method, and launch InAppWebView with some website that needs some input.
  • focus on the text field and see if it's possible to switch to pinyin input method in gboard.

Screenshots or Videos

Video with language switching issue
Before applying the fix, all Chinese input methods will be displayed with just QWERTY input keyboard, which does not allow users to input any Chinese characters.

inappwebview_input_issue

Video after applying the fix
After applying the fix, the input method can be successfully switched, and be used to input Chinese.
inappwebview_input_issue_fixed

To Do

  • double check the original issue to confirm it is fully satisfied
  • add testing notes and screenshots in PR description to help guide reviewers
  • request the "UX" team perform a design review (if/when applicable)

@pichillilorenzo
Copy link
Owner

Thanks! I was waiting for the hybrid composition to be available on the stable channel before doing this. With hybrid composition, probably I can remove also some other workarounds.

I think we need to wait when the hybrid composition is available on the stable channel in order to merge this PR, what do you think?

@plateaukao
Copy link
Contributor Author

that sounds good to me. :) I will keep tracking when it's merged to stable channel.

@plateaukao
Copy link
Contributor Author

Hello @pichillilorenzo ~ 1.20 and 1.20.1 is released on flutter stable channel. If you have time to merge this PR, or integrate hybrid composition in any way in next version, it would be of great help! Thank you. :)

@tneotia
Copy link
Contributor

tneotia commented Aug 21, 2020

@plateaukao Just tried this out for the heck of it, and it does not work. Does something need updating? I double checked myself to make sure I didn't copy anything wrong.

Logs
E/flutter (20797): [ERROR:flutter/lib/ui/ui_dart_state.cc(171)] Unhandled Exception: MissingPluginException(No implementation found for method clearCache on channel com.pichillilorenzo/flutter_inappwebview_0)
E/flutter (20797): #0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:158:7)
E/flutter (20797): <asynchronous suspension>
E/flutter (20797): #1      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:333:12)
E/flutter (20797): #2      InAppWebViewController.clearCache (package:flutter_inappwebview/src/in_app_webview_controller.dart:1546:20)
E/flutter (20797): #3      LoginScreen.build.<anonymous closure>.<anonymous closure> (test/screens/LoginScreen.dart:268:48)
E/flutter (20797): #4      _InAppWebViewState._onPlatformViewCreated (package:flutter_inappwebview/src/in_app_webview.dart:408:30)
E/flutter (20797): #5      _InAppWebViewState.build.<anonymous closure>.<anonymous closure> (package:flutter_inappwebview/src/in_app_webview.dart:370:56)
E/flutter (20797): #6      AndroidViewController.create (package:flutter/src/services/platform_views.dart:753:15)
E/flutter (20797): #7      _rootRunUnary (dart:async/zone.dart:1198:47)
E/flutter (20797): #8      _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter (20797): #9      _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
E/flutter (20797): #10     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
E/flutter (20797): #11     Future._propagateToListeners (dart:async/future_impl.dart:725:32)
E/flutter (20797): #12     Future._completeWithValue (dart:async/future_impl.dart:529:5)
E/flutter (20797): #13     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:40:15)
E/flutter (20797): #14     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:311:13)
E/flutter (20797): #15     MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart)
E/flutter (20797): #16     _rootRunUnary (dart:async/zone.dart:1198:47)
E/flutter (20797): #17     _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter (20797): #18     _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
E/flutter (20797): #19     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
E/flutter (20797): #20     Future._propagateToListeners (dart:async/future_impl.dart:725:32)
E/flutter (20797): #21     Future._completeWithValue (dart:async/future_impl.dart:529:5)
E/flutter (20797): #22     Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:567:7)
E/flutter (20797): #23     _rootRun (dart:async/zone.dart:1190:13)
E/flutter (20797): #24     _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter (20797): #25     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
E/flutter (20797): #26     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
E/flutter (20797): #27     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
E/flutter (20797): #28     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
E/flutter (20797): 
E/flutter (20797): [ERROR:flutter/lib/ui/ui_dart_state.cc(171)] Unhandled Exception: MissingPluginException(No implementation found for method loadUrl on channel com.pichillilorenzo/flutter_inappwebview_0)
E/flutter (20797): #0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:158:7)
E/flutter (20797): <asynchronous suspension>
E/flutter (20797): #1      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:333:12)
E/flutter (20797): #2      InAppWebViewController.loadUrl (package:flutter_inappwebview/src/in_app_webview_controller.dart:1155:20)
E/flutter (20797): #3      LoginScreen._loginMethod (test/screens/LoginScreen.dart:874:20)
E/flutter (20797): #4      _rootRunUnary (dart:async/zone.dart:1198:47)
E/flutter (20797): #5      _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter (20797): #6      _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
E/flutter (20797): #7      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
E/flutter (20797): #8      Future._propagateToListeners (dart:async/future_impl.dart:725:32)
E/flutter (20797): #9      Future._addListener.<anonymous closure> (dart:async/future_impl.dart:393:9)
E/flutter (20797): #10     _rootRun (dart:async/zone.dart:1190:13)
E/flutter (20797): #11     _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter (20797): #12     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
E/flutter (20797): #13     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
E/flutter (20797): #14     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
E/flutter (20797): #15     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
E/flutter (20797): 
E/flutter (20797): [ERROR:flutter/flow/layers/platform_view_layer.cc(25)] Trying to embed a platform view but the PrerollContext does not support embedding
E/flutter (20797): [ERROR:flutter/flow/layers/platform_view_layer.cc(40)] Trying to embed a platform view but the PaintContext does not support embedding
D/AndroidRuntime(20797): Shutting down VM
E/AndroidRuntime(20797): FATAL EXCEPTION: main
E/AndroidRuntime(20797): Process: org.thelatinschool.canvasgrades, PID: 20797
E/AndroidRuntime(20797): java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.accessibility.AccessibilityNodeInfo android.view.View.createAccessibilityNodeInfo()' on a null object reference
E/AndroidRuntime(20797): 	at io.flutter.view.AccessibilityViewEmbedder.getRootNode(AccessibilityViewEmbedder.java:86)
E/AndroidRuntime(20797): 	at io.flutter.view.AccessibilityBridge.createAccessibilityNodeInfo(AccessibilityBridge.java:536)
E/AndroidRuntime(20797): 	at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfVirtualNode(AccessibilityInteractionController.java:1321)
E/AndroidRuntime(20797): 	at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfVirtualNode(AccessibilityInteractionController.java:1331)
E/AndroidRuntime(20797): 	at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfVirtualNode(AccessibilityInteractionController.java:1331)
E/AndroidRuntime(20797): 	at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfVirtualNode(AccessibilityInteractionController.java:1331)
E/AndroidRuntime(20797): 	at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfVirtualNode(AccessibilityInteractionController.java:1331)
E/AndroidRuntime(20797): 	at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfRealNode(AccessibilityInteractionController.java:1234)
E/AndroidRuntime(20797): 	at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchAccessibilityNodeInfos(AccessibilityInteractionController.java:1032)
E/AndroidRuntime(20797): 	at android.view.AccessibilityInteractionController.findAccessibilityNodeInfoByAccessibilityIdUiThread(AccessibilityInteractionController.java:341)
E/AndroidRuntime(20797): 	at android.view.AccessibilityInteractionController.access$400(AccessibilityInteractionController.java:75)
E/AndroidRuntime(20797): 	at android.view.AccessibilityInteractionController$PrivateHandler.handleMessage(AccessibilityInteractionController.java:1396)
E/AndroidRuntime(20797): 	at android.os.Handler.dispatchMessage(Handler.java:107)
E/AndroidRuntime(20797): 	at android.os.Looper.loop(Looper.java:237)
E/AndroidRuntime(20797): 	at android.app.ActivityThread.main(ActivityThread.java:8016)
E/AndroidRuntime(20797): 	at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(20797): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
E/AndroidRuntime(20797): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1076)
D/NetworkSecurityConfig(20797): No Network Security Config specified, using platform default
I/System.out(20797): (HTTPLog)-Static: isSBSettingEnabled false
I/System.out(20797): (HTTPLog)-Static: isSBSettingEnabled false
D/TransportRuntime.SQLiteEventStore(20797): Storing event with priority=HIGHEST, name=FIREBASE_CRASHLYTICS_REPORT for destination cct
D/TransportRuntime.JobInfoScheduler(20797): Scheduling upload for context TransportContext(cct, HIGHEST, MSRodHRwczovL2NyYXNobHl0aWNzcmVwb3J0cy1wYS5nb29nbGVhcGlzLmNvbS92MS9maXJlbG9nL2xlZ2FjeS9iYXRjaGxvZ1xBSXphU3lCcnBTWVQ0RkZMMDlyZUhKaTZIOUZZZGVpU25VVE92Mk0=) with jobId=-2005518719 in 1000ms(Backend next call timestamp 1598041812433). Attempt 1
I/Process (20797): Sending signal. PID: 20797 SIG: 9
Lost connection to device.
flutter doctor -v
[√] Flutter (Channel beta, 1.21.0-9.1.pre, on Microsoft Windows [Version 10.0.19041.423], locale en-US)
    • Flutter version 1.21.0-9.1.pre at C:\flutter
    • Framework revision be9bc8cb39 (3 days ago), 2020-08-18 09:46:08 -0700
    • Engine revision 267070c17a
    • Dart version 2.10.0 (build 2.10.0-7.2.beta)


[√] Android toolchain - develop for Android devices (Android SDK version 30.0.0-rc2)
    • Android SDK at C:\Users\tanay\AppData\Local\Android\sdk
    • Platform android-30, build-tools 30.0.0-rc2
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)
    • All Android licenses accepted.

[√] Android Studio (version 3.6)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin version 46.0.1
    • Dart plugin version 192.8052
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)

[√] VS Code (version 1.48.1)
    • VS Code at C:\Users\tanay\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.13.2

[√] Connected device (1 available)
    • SM G975F (mobile) • 192.168.0.213:5555 • android-arm64 • Android 10 (API 29)

• No issues found!

The lines below just flood the logs constantly and then the app crashes on debug mode.

E/flutter (20797): [ERROR:flutter/flow/layers/platform_view_layer.cc(25)] Trying to embed a platform view but the PrerollContext does not support embedding
E/flutter (20797): [ERROR:flutter/flow/layers/platform_view_layer.cc(40)] Trying to embed a platform view but the PaintContext does not support embedding

@plateaukao
Copy link
Contributor Author

plateaukao commented Aug 21, 2020

for last two lines, you need to modify your android AndroidManifest.xml to add meta-data.

Screenshot_20200822-053242.png

as for first crash log, it seems not related to keyboard input error.

@tneotia
Copy link
Contributor

tneotia commented Aug 21, 2020

Yup adding to my own AndroidManifest fixed it, thanks! Scrolling is so buttery smooth on Android now.

@tneotia
Copy link
Contributor

tneotia commented Aug 22, 2020

@plateaukao I built a release mode app and one thing I noticed is although the webview is super smooth now, any other UI elements on a page with webview are laggy. For example if I have a navigation drawer, its animation is dropping frames.
In my settings page this is not the case, switches turn on and off with no stutters, and page transitions have smooth animations unlike going from my webview screen to the settings screen.
Dont know what exactly would be causing it but it wasnt happening like this before this change. If you need any help with logs/debug I can try and help!

Update: here is where you might be able to see what I'm talking about - settings and webview are like butter but the drawer is laggy, same goes for every other non-webview widget in the webview page.

@Doflatango
Copy link
Contributor

@tneotia Do you running on Android 9 or below? See Hybrid-Composition#performance.

It should be working fine on Android 10, i has tested on 3 devices with Android 10(2 of them have a lower performance CPU) and it looks smooth enough.

@tneotia
Copy link
Contributor

tneotia commented Aug 22, 2020

@Doflatango ohh I see - I looked up this issue but didnt find this doc. I tested on Android 9... that is unfortunate, and grabbing a screenshot and displaying is kind of impractical. Would there be a way to just apply hybrid composition to the webview? Dont think that would be possible, just wondering.

Edit: I read a little bit more and actually understand how hybrid composition works now. I feel like maybe we should wait for this considering the fact that many android devices are not Android 10+, and creating an option for using hybrid composition would likely not be feasible (correct me if I am wrong here). Hybrid composition may be on Flutter stable but I wouldn't consider it to be stable for the vast majority of Android devices - you can really feel the difference when there is any sort of animation, whether it be screen transitions, nav drawer opening/closing, etc. I really hope the Flutter team can find an acceptable solution in the near future for this, though.

@plateaukao
Copy link
Contributor Author

webview is not well supported in flutter for a long time, and hybrid composition is a big breakthrough for android platform, that fixes many long lasting issues. However, don't expect it's going to be stable or performant any time soon.

I reported a crash issue that's 100% reproducible if you use hybrid composition webview in android, and send a PR for this issue 10 days ago, but it's not commented yet til now.
flutter/engine#20475 (comment)

I don't think supporting native platform view is of high priority in flutter dev team; that's why hybrid composition come out so late. You can check all the issues reported about platform view in these two years.

So, if webview is a must for your app, suggest trying the method just mentioned(make a screenshot for it while animation is ongoing), or, just disable any significant animation while webview is used.

A more aggressive step would be, to help check why current implementation is not working well with android under OS 10, and try to send PR to make it better. :) This is out of my capability although I really want to do so.

@tneotia
Copy link
Contributor

tneotia commented Aug 23, 2020

@plateaukao yea I understand what you are saying. Frankly I'm just a college student developing an app for my school, and I dont even want to be a software engineer. I only really understand how to make a Flutter app, not the mechanics behind how the engine works.

I have seen the webview is neglected for quite some time and even the official plugin has a plethora of issues. The problem for me is that my app has to be built around a webview, there is no api I can use to make an actual UI. Dont know why Flutter team doesnt have any wish to work on webview, and it's hard to tell what issues they are working on currently as it is. I will try the screenshot approach though I dont know how well that would work.

I wish I could help out with this as I want flutter to become a matured platform - it has helped me in so many ways and truly is a breakthrough, but it's also outside of my capability.

@plateaukao
Copy link
Contributor Author

plateaukao commented Aug 23, 2020

@tneotia if I were flutter dev team, with limited resource, I would also put my focus on flutter widgets and the cross platform part more, since that's the main strength of flutter since the beginning. As for supporting each platform's native view, it's easily constrained by the platform's original limitation. And sometimes even if they want to, they can only wait for that platform to have better architecture too (like what we wait for hybrid composition in flutter for a better inappwebview plugin ).

Hope that hybrid composition can be stable as soon as possible so people can benefit from flutter's strength and the powerful platform view at the same time. As more and more developers start using flutter, I expect to see more and more input from community too to make it improve faster. :)

@tneotia
Copy link
Contributor

tneotia commented Aug 23, 2020

I completely agree.. I read somewhere that it runs on android 10 well because of a newer api so your point about OS support is very valid.

Imo flutter is already as powerful as React Native and its newer, just think what is achievable in the near future, especially being under Google. I believe within the next year or two we will be seeing leaps and bounds!

@tneotia
Copy link
Contributor

tneotia commented Aug 24, 2020

@pichillilorenzo I think we are good to merge this if it looks good to you, since now we have an option to use this rather than forcing users to adopt Hybrid Composition. Also, no need for each user to include the embedded_views_preview in their AndroidManifest anymore, it is taken care of through the plugin itself.

Added missing `contextMenu` and `windowId` creation params for Android Hybrid Composition
@pichillilorenzo
Copy link
Owner

Thanks!

@pichillilorenzo pichillilorenzo merged commit 4221c99 into pichillilorenzo:master Aug 27, 2020
@tneotia
Copy link
Contributor

tneotia commented Aug 27, 2020

Actually I discovered a bug with this yesterday I was trying to fix, but couldn't get to it. If you don't have the android tag (it just has to be there, no options actually have to be defined), the app doesn't run and says the parameter android is not defined. I think it has something to do with the way I grabbed the useHybridComposition bool - I queried it using widget.initialOptions.android.useHybridComposition.

This will have to be fixed before pushing a new release, do you have any idea what could be going wrong?

@pichillilorenzo
Copy link
Owner

Ok, I fixed also that! Thanks 👍

@plateaukao plateaukao deleted the support_hybrid_composition_in_android branch August 27, 2020 14:33
@plateaukao
Copy link
Contributor Author

just FYI:
Flutter 1.22.0-12.1.pre is released in Beta channel on 9/17/2020. This release fixed the PlatformViewLink (Hybrid Composition) unstable issue described in flutter/flutter#63897

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants