为远程 html 页面从 Android 中的本地资产加载 jQuery

Posted

技术标签:

【中文标题】为远程 html 页面从 Android 中的本地资产加载 jQuery【英文标题】:Loading jQuery from local assets in Android for a remote html page 【发布时间】:2014-08-29 05:41:42 【问题描述】:

我正在尝试从 android webview 读取存储在资产中的本地 javascript 文件 (jQuery)。我不想加载-base-url,因为我的图像和 html 是远程提供的。

总结: - 将本地 jQuery(在 assets 文件夹中)加载到 Android webview 中的远程加载页面中。

经过长时间的无用浏览,我决定在这里提出这个问题。请帮忙。

谢谢!

【问题讨论】:

【参考方案1】:

    定义一个像下面这样的 Javascript 接口,它将从 assets 目录中读取你的 jquery 文件

    class JavaScriptInterface 
    
        @JavascriptInterface
        public String getFileContents()
            return readAssetsContent("jquery.js");
        
    
    

    更新 WebView 以启用 JavaScript 并添加之前定义的 JavaScriptInterface...

    webView.getSettings().setJavaScriptEnabled(true);       
    webView.addJavascriptInterface(new JavaScriptInterface(), "android");
    

    在远程 HTML 中添加 javascript 代码 sn-p 以通过 android JavaScript 接口读取 jquery 文件内容...

    <script type="text/javascript">
    var s = document.createElement('script');
    s.innerHTML = window.android.getFileContents();
    document.head.appendChild(s);
    
    //check if jquery is loaded now...
    if(typeof $ != "undefined") 
        $(document).ready(function() 
            $('body').css('background','green');
        );
     else 
        document.body.innerText = "jQuery NOT loaded";
    
    </script>
    

【讨论】:

这个函数readAssetsContent()在哪里??我必须创建这个还是一个库?【参考方案2】:

首先,在您的 Activity 中,创建静态变量 appContext,它保存应用程序上下文和以下函数:

 //Initialize Application Context
 private static Context appContext;

 //Get Application Context (for use in external functions)
    public static Context getContext() 
        return appContext;
    

...并在onCreate(Bundle savedInstanceState)中设置变量:

     //Set application context (for use in external functions)
     appContext = this;

第二,在下面的单独文件中创建类:

文件:JavaScriptInterface.java

import android.content.Context;
import android.util.Log;
import android.webkit.JavascriptInterface;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;    

class JavaScriptInterface         

    @JavascriptInterface
    public String getFileContents(String assetName)
        return readAssetsContent(MainActivity.getContext(), assetName);
    

    //Read resources from "assets" folder in string
    public String readAssetsContent(Context context, String name) 
        BufferedReader in = null;
        try 
            StringBuilder buf = new StringBuilder();
            InputStream is = context.getAssets().open(name);
            in = new BufferedReader(new InputStreamReader(is));

            String str;
            boolean isFirst = true;
            while ( (str = in.readLine()) != null ) 
                if (isFirst)
                    isFirst = false;
                else
                    buf.append('\n');
                buf.append(str);
            
            return buf.toString();
         catch (IOException e) 
            Log.e("error", "Error opening asset " + name);
         finally 
            if (in != null) 
                try 
                    in.close();
                 catch (IOException e) 
                    Log.e("error", "Error closing asset " + name);
                
            
        

        return null;
    


第三,别忘了初始化你的Webview来使用JavaScriptInterface:

     //Set JS interface from JS/HTML code execution
     mWebView.addJavascriptInterface(new JavaScriptInterface(), "android");

第四,调用android方法getFileContents()用JavaScript在你的HTML中加载本地资源:

       <script type="text/javascript">
          var s = document.createElement('script');
          s.innerHTML = window.android.getFileContents('js/jquery.min.js');
          document.head.appendChild(s);

          //check if jquery is loaded now...
          if(typeof $ != "undefined") 
              $(document).ready(function() 
                    alert("jQuery is loaded!");
             );
           else 
                alert("jQuery is NOT loaded!");
          
       </script>

注意:本示例中的本地资源位于/assets/js/ 子文件夹中。

【讨论】:

最重要的检查是jsInterface在一个单独的文件中。解释是GODLIKE!这只是关于问题的内容。【参考方案3】:

在我的 html 页面中,我刚刚添加了一个这样的标签。

<script type="text/javascript" src="file:///android_asset/jquery.js"></script>
<script type="text/javascript" src="file:///android_asset/englArrIni.js"></script>
<script type="text/javascript" src="file:///android_asset/point.js"></script>
<script type="text/javascript" src="file:///android_asset/dataManager.js"></script>

当你加载你的 url 时,它会自动加载所有的 js 文件。我想这对你有帮助。

【讨论】:

当您对答案投反对票时,请发表评论。 问题说远程页面。表示无法访问页面源,否则就是小菜一碟 我因为投反对票而错过了这个答案,在某些情况下这是一个非常合理的答案(至少在我的情况下)。我花了一个多小时在别处找到(相同的)解决方案。

以上是关于为远程 html 页面从 Android 中的本地资产加载 jQuery的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在页面重新加载之间保存远程资源的 css/js 更改或将远程资源映射到 devtools 中的本地?

android webView 当用loadDataWithBaseURL加载本地html时如何实现后退到上一页面

如何查看git远程仓库中的文件

Android 中的 Service 全面总结详解下

iframe 从远程访问本地页面

Android分享笔记 Android的webview加载本地html本apk内html和远程URL