【问题标题】:Android Webview Javascript - References to Scripts not workingAndroid Webview Javascript - 对脚本的引用不起作用
【发布时间】:2015-01-22 21:24:59
【问题描述】:

在 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(),不行。

尝试了所有可能的路径方案。没有任何效果。

从文件夹中删除所有脚本并将它们放在根级别,并将链接修改为没有路径,只是文件名。还是不行。这也太奇怪了。

【问题讨论】:

    标签: android angularjs webview


    【解决方案1】:

    我设法通过以下方式做了类似的事情:

    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>
    

    另外,我的文件结构如下

    希望对你有帮助:)

    【讨论】:

    • 这应该可行,看起来很合乎逻辑。但有趣的是,它不起作用。我应该尝试 Eclipse 而不是 Android Studio。
    • 我的开发系统一定有严重问题,它在 Eclipse 上也不起作用。
    • 奇怪(在 4.3、4.4.4 和 5.0 上测试过,似乎工作正常) - 虽然没有用 gradle 测试。显示资产 html 页面,对吗? (只有引用不起作用)教导说资产文件夹可能没有按应有的方式进入 apk。
    • 是的。这真的很奇怪。 Android 和 iOS 都在发生这种情况。我现在想的是在几台不同的机器上进行测试,看看会发生什么。
    • 我终于找到了问题所在,请看我的回答。这是基本标签。我奖励你,因为你的 HTML 模板让我意识到我所拥有的额外的东西是基本标签。谢谢。
    【解决方案2】:

    尝试在您的源路径中的“lib”前面添加一个正斜杠(因为它是一个相对调用,浏览器将为您完成它http://domain/lib/jquery.min.js 而不是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>
    

    【讨论】:

    • 在发布此问题之前很久就尝试过额外的正斜杠。坦率地说,我曾认为它会起作用。但遗憾的是,事实并非如此。
    • 我更新了我的答案 - 我相信你需要在 AngularJS 中使用 ng-src 指令
    • 脚本驻留在服务器上还是在 Android 设备上的“lib”文件夹中?
    • 在 lib 文件夹中。
    • 原来你可能需要使用 WebView.loadDataWithBaseURL()。这是一个示例:stackoverflow.com/questions/9414312/…
    【解决方案3】:

    我还没有尝试过,但将您的 index.html 页面放入字符串并将其作为数据传递。然后 baseUrl 是 http://domain.com

    public void loadDataWithBaseURL (String baseUrl, String data, String mimeType, String encoding, String historyUrl)
    

    具有本地和互联网(互联网和内部网)资源的 Webview。您必须使用 loadDataWithBaseURL 并且所有互联网资源都必须是 http:// 或者所有文件访问都必须是 file:// 来自网络的任何资源也必须使用 http:// 指定,即来自网络的任何链接等都不能是//i/image.jpg,它们必须是http://www.example.com/i/image.jpg。即 web 或文件系统必须完全合格。

    下面我通过传入文件的完整路径名来使用文件系统中的本地目录(它可以获取目录) 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", "");
                        }
    

    【讨论】:

    • 花了很长时间才让 file:/// 正常工作。继续努力,你会得到它。
    • 我发现了问题。在 Android 端并没有错。我的 HTML 中有一个导致问题的基本标记。谢谢。
    【解决方案4】:

    经过大量的探索,以及回答者的大量帮助,我的代码中的罪魁祸首是base 标签。我删除了它,也删除了 html5mode 的东西。所以,总结一下,我删除了以下内容:

     <base href="/">  
    

    $locationProvider.html5Mode(true);
    

    一切都开始工作了。

    【讨论】:

    • 这两行在哪里?
    【解决方案5】:

    很简单:

    1. 在 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{}
    
    1. 从 index.html 文件中删除 &lt;base href="/"&gt;
    2. 运行命令npm run build
    3. 双击 dist 文件夹中的 index.html 文件。

    您的应用将运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-09
      • 1970-01-01
      • 2011-11-24
      • 1970-01-01
      • 1970-01-01
      • 2017-10-06
      • 2014-07-31
      • 1970-01-01
      相关资源
      最近更新 更多