[TIMOB-25859] Android: Delay WebView Ti.App.fireEvent() to be fired after page load
GitHub Issue | n/a |
---|---|
Type | Improvement |
Priority | Medium |
Status | Closed |
Resolution | Won't Do |
Resolution Date | 2018-10-24T21:10:00.000+0000 |
Affected Version/s | n/a |
Fix Version/s | n/a |
Components | Android |
Labels | android, evalJS, webview |
Reporter | Joshua Quick |
Assignee | Joshua Quick |
Created | 2018-03-12T21:31:53.000+0000 |
Updated | 2018-10-24T21:10:50.000+0000 |
Description
*Summary:*
The JavaScript within a WebView's HTML can call
Ti.App.fireEvent()
to communicate with the Titanium JavaScript side. It currently fires events immediately. The problem with this is if the listener immediately calls WebView.evalJS()
to communicate back, it'll always timeout on Android if the web page hasn't finished loading yet and the Titanium runtime runs on the main UI thread (the default). This makes it less convenient to use.
*Steps to Reproduce:*
Build and run attached [^WebViewInteropTest.js] on Android.
Observe the Android log.
*Result:* AnTimeout waiting to evaluate JS
warning message appears in the log.
*Expected Result:*
The evalJS()
calls should succeed. A countdown message "Reload in: X" should appear in the web page, starting from 5. When it counts down to zero, the page should reload.
*Cause:*
The WebView.evalJS()
call will not work until the "load" event has been received from the WebView. This is because Titanium injects a "polling" script into the web page in the WebViewClient.onPageFinished()
call...
https://github.com/appcelerator/titanium_mobile/blob/master/android/modules/ui/src/java/ti/modules/titanium/ui/widget/webview/TiWebViewClient.java#L45
This polling script is responsible for fetching/evaluating the script added to the stack by the evalJS()
call...
https://github.com/appcelerator/titanium_mobile/blob/master/android/modules/ui/src/java/ti/modules/titanium/ui/widget/webview/TiWebViewBinding.java#L151
Since evalJS()
is getting called before the web page has finished loading, the evalJS()
call will always fail with a timeout warning when the Titanium runtime runs on the main UI thread.
*Recommended Solution:*
Queue all Ti.App.fireEvent()
calls made within the HTML and do not fire them until the page has finished loading.
*Work-Around:*
Use the new async version of WebView.evalJS()
that was introduced into 7.5.0. It does not have this issue.
Attachments
File | Date | Size |
---|---|---|
WebViewInteropTest.js | 2018-10-24T21:03:12.000+0000 | 2012 |
PR (master): https://github.com/appcelerator/titanium_mobile/pull/9931
Note to [~bimmel]: Update https://wiki.appcelerator.org/display/guides2/Communication+Between+WebViews+and+Titanium#CommunicationBetweenWebViewsandTitanium-Remotewebcontent once this release has happened.
Waiting for resolving conflicts
I've confirmed that the async version of
WebView.evalJS()
does not have this problem, which is a new feature we've added in 7.5.0. See: [TIMOB-25862]It is recommended that you use the async version of
WebView.evalJS()
instead. Closing as won't fix.