在构建发布的apk时,react native-webview不能呈现本地html。[英] react native - webview does not render local html when building release apk

本文是小编为大家收集整理的关于在构建发布的apk时,react native-webview不能呈现本地html。的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我在WebView中呈现了本地HTML的应用程序,它在iOS和Android都会很好.它是嵌入SVG标签的HTML.

但是,但我在Android上生成了APK并尝试运行在我的手机上,它只是没有渲染.

即使.ipa文件导出

,也适用于iOS.
const VECTOR_BODY_HTML = require('../custom_views/vector-body.html');
...
         <WebView
           ref={component => this.mWebView = component}

           automaticallyAdjustContentInsets = {false}
           contentInset={{top:0 , left:0 ,bottom:-20, right:0}}

           source = {VECTOR_BODY_HTML}
           scalesPageToFit = {false}

           onLoad = {() => {
               this.updateBodyViewBox(bodyWidth, bodyHeight);
               this.initColorMap();
               this.populateBodyMap(15)
             }
             }
           onMessage = {(data) => {this.onMessage(data);}}

           style = {{height:bodyHeight}}
          >
          </WebView>

推荐答案

好的,这是一个复杂的问题.基本上,Require()在调试模式下使用iOS和Android工作,但构建Android APK以便发布一切顺从.所以我会把这个陷入后遗症,毫无疑问,未来我.

for setup,让我们假设文件名是your.html,它位于src/assets/your.html文件夹中.

所以步骤1)您需要使用跨平台支持更新您的<WebView />组件:

import {Platform, WebView} from 'react-native';    

<WebView
  source={Platform.OS === 'ios' ? 
    require('../src/assets/your.html') :
    {uri: 'file:///android_asset/your.html'}
  }
  domStorageEnabled
  javaScriptEnabled
/>
所以这里发生了什么是,您需要告诉Android允许访问DOM Storage 和,您需要启用JavaScript(除非您不这样做,否则它很好).显然,默认情况下,默认在Android上禁用了javascript.

在这里做什么来源是,如果平台是iOS,我们只需正常需要文件,一切都将为dev/prod工作.但是,对于android,我们需要告诉它从android的默认Android存储位置加载文件,这是file:///android_asset/的默认的Android存储位置.此文件直接对应于位于android/app/src/main/assets/的文件夹,这是您可以将your.html复制到的.所以它看起来像android/app/src/main/assets/your.html.

并且一切都将在这一点上工作 - 但是,您可能会发现将文件直接复制令人讨厌的令人讨厌.至少,我确实如此.

So for第2步)您可以升级您的应用程序build.gradle文件以自动更新您的资产.因此,请继续并打开位于android/app/build.gradle的App Build.gradle文件.在底部的某个地方(其他task命令)继续前进并放置:

task copyReactNativeHTML(type: Copy) {
  from '../../src/assets/'
  into 'src/main/assets'
}

gradle.projectsEvaluated {
  bundleDebugJsAndAssets.dependsOn(copyReactNativeHTML)
  bundleReleaseJsAndAssets.dependsOn(copyReactNativeHTML)
}

现在,您应该能够将文件自动复制到正确的资产文件夹中,以便您可以通过Android_Asset从JavaScript访问它们.

那是它!有点,它应该为大多数用例工作,但是有另一个关于Android的奇怪的事情,并用Proguard缩小你的建造.基本上,如果你想使用它,你需要确保保持your.html上面.

for(可选)步骤3)打开位于android/app/proguard-rules.pro的Proguard设置文件,然后添加以下内容:

-keepclassmembers class fqcn.of.javascript.interface.for.webview {
  public *;
}

就是这样,应该为您设置一切,以便使用webviews crossplatatform.我不能真正为这篇文章提供信誉,因为我刚从 https://github.com/facebook/reacont-native/issues/16133 .特别是,Arshiamidos和Scottschmitz解决方案是最开悟的.我建议我们都去买啤酒:).

其他推荐答案

 <WebView
  style={{
          flex: 1,
          marginLeft: Platform.OS === 'ios' ? 25 : 0,
          marginRight: Platform.OS === 'ios' ? 25 : 0,
          width: deviceWidth - 0,
          borderRadius: 4
          }}
          originWhitelist={['*']}
        source={Platform.OS === 'ios' ?
                require('../../../components/Heartrate.html') :
                {uri: 'file:///android_asset/Heartrate.html'}
                 }
         bounces={false}
         javaScriptEnabled={true}
         directionalLockEnabled={true}
         vertical={false}
         ref={(webView) => this.heartRateWebView = webView}
    />

在Android 中放入Android中的HTML - > Assets文件夹

和iOS将您的HTML放入文件夹中的React Native项目中

在此处输入图像描述

本文地址:https://www.itbaoku.cn/post/1937989.html

问题描述

I have rendering local html in webview for my application, it was going great on both iOS and Android. It's an html with svg tags embedded.

But as soon as I generated an apk on Android and tried running is locally on my phone, it just doesn't render.

Works well on iOS even when .ipa file is exported

const VECTOR_BODY_HTML = require('../custom_views/vector-body.html');
...
         <WebView
           ref={component => this.mWebView = component}

           automaticallyAdjustContentInsets = {false}
           contentInset={{top:0 , left:0 ,bottom:-20, right:0}}

           source = {VECTOR_BODY_HTML}
           scalesPageToFit = {false}

           onLoad = {() => {
               this.updateBodyViewBox(bodyWidth, bodyHeight);
               this.initColorMap();
               this.populateBodyMap(15)
             }
             }
           onMessage = {(data) => {this.onMessage(data);}}

           style = {{height:bodyHeight}}
          >
          </WebView>

推荐答案

Ok so this is a complex issue. Basically, require() works fine with iOS and Android in debug modes but once you build a Android apk for release everything goes downhill. So I'll break this down into stages for posterity and, without a doubt, future me.

For setup, let's assume your file name is your.html and that it's located in your src/assets/your.html folder.

So step 1) You'll need to update your <WebView /> component with cross platform support in mind:

import {Platform, WebView} from 'react-native';    

<WebView
  source={Platform.OS === 'ios' ? 
    require('../src/assets/your.html') :
    {uri: 'file:///android_asset/your.html'}
  }
  domStorageEnabled
  javaScriptEnabled
/>

So what's going on here is that you need to tell android to allow access to dom storage and that you need javascript enabled (unless you don't then it's fine). Apparently, javascript is enabled by default on iOS and disabled by default on Android.

What source is doing here is, if the Platform is iOS, we just require files normally and everything will work for dev/prod. However, for android we need to tell it to load the file from the default android storage location for android which is file:///android_asset/. This file corresponds directly with the folder located at android/app/src/main/assets/ this is where your can copy your.html to. So it would look like android/app/src/main/assets/your.html.

And everything will work at this point - however, you might find copying your files directly incredibly annoying. At least, I did.

So for step 2) you can upgrade your app build.gradle file to automatically update your assets. So go ahead and open your app build.gradle file located at android/app/build.gradle. Somewhere towards the bottom (where other task commands are) go ahead and put:

task copyReactNativeHTML(type: Copy) {
  from '../../src/assets/'
  into 'src/main/assets'
}

gradle.projectsEvaluated {
  bundleDebugJsAndAssets.dependsOn(copyReactNativeHTML)
  bundleReleaseJsAndAssets.dependsOn(copyReactNativeHTML)
}

And now you should be able to have your files automatically copied into the correct assets folder so you can access them from javascript via android_asset.

And that's it! Kind of, it should work for most use cases but there is another strange thing about android and minifying your build with ProGuard. Basically, if you want to use it you need to make sure to keep your.html unmangled.

So for (optional) step 3) Open your proguard settings file located at android/app/proguard-rules.pro and add to it the following:

-keepclassmembers class fqcn.of.javascript.interface.for.webview {
  public *;
}

And that's it, everything should be set for you to use WebViews crossplatform. I can't really take credit for this post as I just cobbled together a bunch of peoples solutions from https://github.com/facebook/react-native/issues/16133. In particular, Arshiamidos and scottschmitz solutions were most enlightening. I'd suggest we all go buy them a beer :).

其他推荐答案

 <WebView
  style={{
          flex: 1,
          marginLeft: Platform.OS === 'ios' ? 25 : 0,
          marginRight: Platform.OS === 'ios' ? 25 : 0,
          width: deviceWidth - 0,
          borderRadius: 4
          }}
          originWhitelist={['*']}
        source={Platform.OS === 'ios' ?
                require('../../../components/Heartrate.html') :
                {uri: 'file:///android_asset/Heartrate.html'}
                 }
         bounces={false}
         javaScriptEnabled={true}
         directionalLockEnabled={true}
         vertical={false}
         ref={(webView) => this.heartRateWebView = webView}
    />

In android Put Your Html in Android --> Asssets Folder

and iOS Put your Html in React Native Project inside your Folder

enter image description here