我已经在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>
答案 0 :(得分:3)
好的,这是一个复杂的问题。基本上,require()在调试模式下可以与iOS和Android一起使用,但是一旦你构建一个Android apk for release,一切都会走下坡路。因此,我将这一点分解为后人的阶段,毫无疑问,是未来的我。
要进行设置,请假设您的文件名为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存储和你需要启用javascript(除非你不这样做&#39) ;很好)。显然,默认情况下,iOS在iOS上启用,默认情况下在Android上禁用。
这里做的是,如果平台是iOS,我们只需要正常的文件,一切都适用于dev / prod。但是,对于android我们需要告诉它从android的默认android存储位置加载文件file:///android_asset/
。此文件直接与位于android/app/src/main/assets/
的文件夹对应,您可以将your.html
复制到该文件夹。所以它看起来像android/app/src/main/assets/your.html
。
此时一切都会正常工作 - 但是,您可能会发现直接复制文件令人难以置信令人讨厌。至少,我做到了。
因此,对于第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
不加标记。
因此对于(可选)步骤3)打开位于android/app/proguard-rules.pro
的proguard设置文件并添加以下内容:
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
public *;
}
就是这样,应该为您设置所有内容以使用WebViews跨平台。我不能真正赞美这篇文章,因为我刚刚从https://github.com/facebook/react-native/issues/16133拼凑了一堆人民解决方案。特别是,Arshiamidos和scottschmitz解决方案最具启发性。我建议大家都给他们买啤酒:)。
答案 1 :(得分:0)
<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 中将HTML放入Android->资产文件夹
和iOS将HTML放入文件夹中的React Native Project中
答案 2 :(得分:0)
我正在使用 webview 在我的本机应用程序中显示一个图表。它在开发过程中加载图表,但不在发布 apk 中显示。
我的网页视图代码如下。
<View
style={{ flex: 1, backgroundColor: 'yellow', alignSelf: 'stretch' }}>
<WebView
ref={(r) => (this.webRef = r)}
originWhitelist={['*']}
source={{ html: this.html() }}
style={{ width: 380, height: 300, backgroundColor: 'lightblue' }}
domStorageEnabled={true}
javaScriptEnabled={true}
injectedJavaScriptBeforeContentLoaded={this.pipeConsoleLog()}
onMessage={this.handleMessage.bind(this)}
/>
</View>
而 html() 就像...
html() {
return `
<html lang="en">
<head>
<title>seating chart</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn-na.seatsio.net/chart.js"></script>
</head>
<body>
<script>
let promises = [];
let promiseCounter = 0;
const resolvePromise = (promiseId, data) => {
promises[promiseId](data)
}
</script>
<div id="chart"></div>
<script>
let chart = new seatsio.SeatingChart(${this.configAsString()}).render();
</script>
</body>
</html>
`;
}
但是图表没有加载。我试图将以下代码放入 Proguard 文件中,但应用程序崩溃了。
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
public *;
}