Android Webview Javascript - 对脚本的引用不起作用
Android Webview Javascript - References to Scripts not working
在 Android Studio 1.0.1 上开发,API 21. 以下是文件夹结构 -
它本质上是一个基于 AngularJS 的应用程序,我想将其包装在 webview 容器中,并在 Android 上 运行。
我的 Android 代码是 -
WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
myWebView.setWebChromeClient(new WebChromeClient());
String filePath = "file:///android_asset/www/index.html";
myWebView.loadUrl(filePath);
html中的引用都是相对的-
<script src="lib/jquery.min.js"></script>
<script src="lib/angular.min.js"></script>
<script src="lib/angular-route.min.js"></script>
<script src="lib/bootstrap.min.js"></script>
但有趣的是,我已经搜索了大部分地方,但我不确定哪里出错了。我的参考资料根本不起作用!所以我无法访问我的 lib 文件、我的脚本、我的 css。
另外,如果我 运行 webview 中的外部 angular 网页,使用相同的 Java 代码,它 运行 完美!
感谢任何帮助。
注意:请不要建议使用Cordova/PhoneGap。原生化是一个项目要求(坦率地说,我不明白为什么,但我只是一个没有发言权的开发人员)。
旁注: 我在 iOS 网络视图中遇到了同样的问题。引用无效!
更新
尝试了以下操作:
试过loadDataWithBaseURL()
,没用。
尝试了所有可能的路径方案。没有任何效果。
从文件夹中删除了所有脚本并将它们放在根级别,并将链接修改为没有路径,只有文件名。还是不行。这太奇怪了。
尝试像这样在您的源路径中的 "lib" 前面放置一个正斜杠(因为它是一个相对调用,浏览器会为您完成它 http://domain/lib/jquery.min.js instead of http://domain.comlib/jquery.min.js)。
更新 - 我相信 AngularJS 使用 ng-src 指令来包含外部资源:
<script ng-src="/lib/jquery.min.js"></script>
<script ng-src="/lib/angular.min.js"></script>
<script ng-src="/lib/angular-route.min.js"></script>
<script ng-src="/lib/bootstrap.min.js"></script>
或者,如果您真的不需要像这样动态的代码,您也可以自己完成路径(这也是确保一切正常工作的快速测试):
<script ng-src="http://domain.com/lib/jquery.min.js"></script>
<script ng-src="http://domain.com/lib/angular.min.js"></script>
<script ng-src="http://domain.com/lib/angular-route.min.js"></script>
<script ng-src="http://domain.com/lib/bootstrap.min.js"></script>
我还没有尝试过,但是将您的 index.html 页面放入一个字符串中并将其作为数据传入。然后 baseUrl 是 http://domain.com
public void loadDataWithBaseURL (String baseUrl, String data, String mimeType, String encoding, String historyUrl)
具有本地和互联网(Internet 和 Intranet)资源的 Webview。您必须使用 loadDataWithBaseURL 并且所有 interweb 资源都必须是 http:// 或者所有文件访问必须是 file:// 网络上的任何资源也必须用 http:// 指定,这是来自网络的任何链接等都不能是 //i/image.jpg 它们必须是 http://www.example.com/i/image.jpg。即网络或文件系统必须完全合格。
下面我通过传入文件的完整路径名来使用文件系统中的本地目录(它可以获取目录) html 被放入一个字符串中。因为我使用的是 loadDataWithBaseURL,所以当它以 http://
为前缀时,我也可以访问互联网
StringBuilder sb = new StringBuilder();
sb.append("<html><body><div style=\"width:100%; text-align:center; font-size:large;\">");
sb.append(kmlmo.markeroptions.getTitle());
sb.append("</div>");
sb.append("<a href = \"http://www.example.com/link.html\">mylink</a>");
sb.append(kmlmo.markeroptions.getSnippet());
sb.append("</body></html>");
View v = getView();
if (v != null) {
wv = (WebView) v.findViewById(R.id.webView1);
if (wv != null) {
String localPath = "file://" + kmlmo.path;
String temp = sb.toString();
wv.loadDataWithBaseURL(localPath, temp, "text/html",
"UTF-8", "");
}
我设法通过以下方式做了类似的事情:
WebView webView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webView.setWebChromeClient(new WebChromeClient());
try {
String html = readAssetFile("www/index.html");
webView.loadDataWithBaseURL("file:///android_asset/www/", html, "text/html", "UTF-8", null);
} catch (IOException e) {
}
其中 'readAssetFile' 是:
private String readAssetFile(String fileName) throws IOException {
StringBuilder buffer = new StringBuilder();
InputStream fileInputStream = getAssets().open(fileName);
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(fileInputStream, "UTF-8"));
String str;
while ((str=bufferReader.readLine()) != null) {
buffer.append(str);
}
fileInputStream.close();
return buffer.toString();
}
此外,我的页面很简单 - 只是为了测试图像、angularjs 库和 css 样式表:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/mystyle.css">
<script src="libs/angular.min.js"></script>
</head>
<body>
<img src="images/IMG_7765.JPG" alt="De nada" width="200" height="300">
<div ng-app="">
<p>Input something in the input box:</p>
<p>Name: <input type="text" ng-model="name" value="John"></p>
<p ng-bind="name"></p>
</div>
</body>
</html>
另外,我的文件结构如下
希望对您有所帮助:)
经过大量探索,以及回答者的大量帮助,我的代码中的罪魁祸首是 base
标记。我删除了它,还删除了 html5mode 东西。所以,总而言之,我删除了以下内容:
<base href="/">
和
$locationProvider.html5Mode(true);
一切都开始工作了。
很简单:
- 在app.module.ts
中添加此代码
//in App.module.ts :
//import these packages
import { APP_BASE_HREF, LocationStrategy, HashLocationStrategy } from '@angular/common';
// add these packages into providers as below :
@NgModule({
imports:
[
.....
],
declarations:
[
....
],
providers:
[
....
{ provide: APP_BASE_HREF, useValue: '/' },
{ provide: LocationStrategy, useClass: HashLocationStrategy },
....
]
....
})
export class Appmodule{}
- 从 index.html 文件中删除
<base href="/">
- 运行 命令
npm run build
- 双击 dist 文件夹中的 index.html 文件。
您的应用将 运行。
在 Android Studio 1.0.1 上开发,API 21. 以下是文件夹结构 -
它本质上是一个基于 AngularJS 的应用程序,我想将其包装在 webview 容器中,并在 Android 上 运行。
我的 Android 代码是 -
WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
myWebView.setWebChromeClient(new WebChromeClient());
String filePath = "file:///android_asset/www/index.html";
myWebView.loadUrl(filePath);
html中的引用都是相对的-
<script src="lib/jquery.min.js"></script>
<script src="lib/angular.min.js"></script>
<script src="lib/angular-route.min.js"></script>
<script src="lib/bootstrap.min.js"></script>
但有趣的是,我已经搜索了大部分地方,但我不确定哪里出错了。我的参考资料根本不起作用!所以我无法访问我的 lib 文件、我的脚本、我的 css。 另外,如果我 运行 webview 中的外部 angular 网页,使用相同的 Java 代码,它 运行 完美!
感谢任何帮助。
注意:请不要建议使用Cordova/PhoneGap。原生化是一个项目要求(坦率地说,我不明白为什么,但我只是一个没有发言权的开发人员)。
旁注: 我在 iOS 网络视图中遇到了同样的问题。引用无效!
更新
尝试了以下操作:
试过loadDataWithBaseURL()
,没用。
尝试了所有可能的路径方案。没有任何效果。
从文件夹中删除了所有脚本并将它们放在根级别,并将链接修改为没有路径,只有文件名。还是不行。这太奇怪了。
尝试像这样在您的源路径中的 "lib" 前面放置一个正斜杠(因为它是一个相对调用,浏览器会为您完成它 http://domain/lib/jquery.min.js instead of http://domain.comlib/jquery.min.js)。
更新 - 我相信 AngularJS 使用 ng-src 指令来包含外部资源:
<script ng-src="/lib/jquery.min.js"></script>
<script ng-src="/lib/angular.min.js"></script>
<script ng-src="/lib/angular-route.min.js"></script>
<script ng-src="/lib/bootstrap.min.js"></script>
或者,如果您真的不需要像这样动态的代码,您也可以自己完成路径(这也是确保一切正常工作的快速测试):
<script ng-src="http://domain.com/lib/jquery.min.js"></script>
<script ng-src="http://domain.com/lib/angular.min.js"></script>
<script ng-src="http://domain.com/lib/angular-route.min.js"></script>
<script ng-src="http://domain.com/lib/bootstrap.min.js"></script>
我还没有尝试过,但是将您的 index.html 页面放入一个字符串中并将其作为数据传入。然后 baseUrl 是 http://domain.com
public void loadDataWithBaseURL (String baseUrl, String data, String mimeType, String encoding, String historyUrl)
具有本地和互联网(Internet 和 Intranet)资源的 Webview。您必须使用 loadDataWithBaseURL 并且所有 interweb 资源都必须是 http:// 或者所有文件访问必须是 file:// 网络上的任何资源也必须用 http:// 指定,这是来自网络的任何链接等都不能是 //i/image.jpg 它们必须是 http://www.example.com/i/image.jpg。即网络或文件系统必须完全合格。
下面我通过传入文件的完整路径名来使用文件系统中的本地目录(它可以获取目录) html 被放入一个字符串中。因为我使用的是 loadDataWithBaseURL,所以当它以 http://
为前缀时,我也可以访问互联网StringBuilder sb = new StringBuilder();
sb.append("<html><body><div style=\"width:100%; text-align:center; font-size:large;\">");
sb.append(kmlmo.markeroptions.getTitle());
sb.append("</div>");
sb.append("<a href = \"http://www.example.com/link.html\">mylink</a>");
sb.append(kmlmo.markeroptions.getSnippet());
sb.append("</body></html>");
View v = getView();
if (v != null) {
wv = (WebView) v.findViewById(R.id.webView1);
if (wv != null) {
String localPath = "file://" + kmlmo.path;
String temp = sb.toString();
wv.loadDataWithBaseURL(localPath, temp, "text/html",
"UTF-8", "");
}
我设法通过以下方式做了类似的事情:
WebView webView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webView.setWebChromeClient(new WebChromeClient());
try {
String html = readAssetFile("www/index.html");
webView.loadDataWithBaseURL("file:///android_asset/www/", html, "text/html", "UTF-8", null);
} catch (IOException e) {
}
其中 'readAssetFile' 是:
private String readAssetFile(String fileName) throws IOException {
StringBuilder buffer = new StringBuilder();
InputStream fileInputStream = getAssets().open(fileName);
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(fileInputStream, "UTF-8"));
String str;
while ((str=bufferReader.readLine()) != null) {
buffer.append(str);
}
fileInputStream.close();
return buffer.toString();
}
此外,我的页面很简单 - 只是为了测试图像、angularjs 库和 css 样式表:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/mystyle.css">
<script src="libs/angular.min.js"></script>
</head>
<body>
<img src="images/IMG_7765.JPG" alt="De nada" width="200" height="300">
<div ng-app="">
<p>Input something in the input box:</p>
<p>Name: <input type="text" ng-model="name" value="John"></p>
<p ng-bind="name"></p>
</div>
</body>
</html>
另外,我的文件结构如下
希望对您有所帮助:)
经过大量探索,以及回答者的大量帮助,我的代码中的罪魁祸首是 base
标记。我删除了它,还删除了 html5mode 东西。所以,总而言之,我删除了以下内容:
<base href="/">
和
$locationProvider.html5Mode(true);
一切都开始工作了。
很简单:
- 在app.module.ts 中添加此代码
//in App.module.ts :
//import these packages
import { APP_BASE_HREF, LocationStrategy, HashLocationStrategy } from '@angular/common';
// add these packages into providers as below :
@NgModule({
imports:
[
.....
],
declarations:
[
....
],
providers:
[
....
{ provide: APP_BASE_HREF, useValue: '/' },
{ provide: LocationStrategy, useClass: HashLocationStrategy },
....
]
....
})
export class Appmodule{}
- 从 index.html 文件中删除
<base href="/">
- 运行 命令
npm run build
- 双击 dist 文件夹中的 index.html 文件。
您的应用将 运行。