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);

一切都开始工作了。

很简单:

  1. 在app.module.ts
  2. 中添加此代码
//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{}
  1. 从 index.html 文件中删除 <base href="/">
  2. 运行 命令 npm run build
  3. 双击 dist 文件夹中的 index.html 文件。

您的应用将 运行。