ReactNative - Webview不在Android上执行injectJavaScript

Far*_*den 7 android webview react-native

我无法在ReactNative上获取Webview以在物理Android设备上执行注入的JavaScript.在过去的两天里,我尽可能地搜索网络,但仍未找到解决方案.测试结果如下:

  1. iOS模拟器 - 一切都很好
  2. iPhone - 一切都很好
  3. Android模拟器 - 一切都很好
  4. 物理设备,索尼Xperia Z2,索尼Xperia Z5 Compact和LG G4 - 没什么

我的Webview定义如下:

<WebView
  style={styles.webView}
  source={{
    html: html,
    baseUrl: 'web/'
  }}
  injectedJavaScript={'render(' + JSON.stringify(this.state.data) + ');'}
  javaScriptEnabledAndroid={true}
  scrollEnabled={false}
  bounces={false}
  renderLoading={() => <LoadingIndicator />}
/>
Run Code Online (Sandbox Code Playgroud)

我也尝试过指定javaScriptEnabled,但无济于事.我还尝试使用较小的脚本来对页面上的元素进行着色或使用消息将消息发回给应用程序window.postMessage,但没有任何反应.我需要将数据注入HTML,这将根据提供的数据为我呈现图形.我最后的办法是手动构建HTML,并附加数据作为提供给Webview的标记的一部分,但我真的希望保持简单,让它按照应有的方式工作.

我正在使用最新版本的ReactNative(0.41),手机正在运行Android 6+.

Dav*_*lle 6

我刚刚发现Android WebView似乎将任何JS注入单行,即使它包含换行符.这意味着丢失的分号肯定会导致问题,或者,在我的情况下,分隔的注释//.使用/**/注释我的注入JavaScript再次工作.


Far*_*den 4

好吧,在让这个问题开放一段时间并找到解决问题的(不是那么优雅的)解决方案之后,我决定分享我最终所做的事情:

  1. 我按照以下方式声明了要通过常量字符串传递到 WebView 的 HTML:const html = '<html>...<script>...[INJECTEDSCRIPT]</script></html>';
  2. componentDidMount()我在React 组件生命周期中检索了数据,并使用以下命令为其设置了状态变量this.setState({ data: retrievedData });
  3. 当然,这迫使组件重新渲染自身,之后我现在可以将数据“传递”到 WebView
  4. 由于我无法找到任何优雅或可用的方式来使用该injectedJavaScript属性以我想要的方式工作(如问题中所述),我只好用[INJECTEDSCRIPT]序列化数据替换 HTML 常量中的值。

我知道,这不是最优雅的解决方案,但它是我可以在多种设备和模拟器配置上可靠工作的唯一解决方案。示例,为简洁起见进行了编辑,如下:

const html = `
<!DOCTYPE html>
<html>
  <head>...</head>
  <body>...</body>
  <script>
    var render = function (data) {
      ...
    };
    [INJECTEDSCRIPT]
  </script>
</html>`;

export class GraphComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  componentDidMount = () => {
    SERVICE.getData().done((data) => {
      this.setState({ data: data });
    });
  }
  render = () => {
    if (!this.state.data)
      return <LoadingIndicator />;
    let serializedData = JSON.stringify(this.state.data);
    return
      <WebView
        style={styles.webView}
        source={{
          html: html.replace('[INJECTEDSCRIPT]', 'render(' + serializedData + ');'),
          baseUrl: 'web/'
        }}
        scrollEnabled={false}
        bounces={false}
        renderLoading={() => <LoadingIndicator />}
      />;
  }
}
Run Code Online (Sandbox Code Playgroud)