APP在加载外部html时选择加载本地的js、css、img等资源文件(上:安卓篇)

最近在做一个arcgis地图相关的项目,好不容易搞的差不多了,测试时发现在打开服务器上加载arcgis地图服务的html文件时,竟然要花差不多10秒钟时间,有时候甚至还打不开!!

还是用神器chrome测试url,测试发现在初始化地图之前加载arcgis/init.js这个arcgis的依赖文件,要花很长时间,有时候都加载不出来,这个文件900多k,差不多1M,放在现在的4G环境下应该是什么压力的,但是这样既费时还消耗用户的流量……

解决方法我先想到的是做缓存,就第一次加载耗时耗力,后面就可以直接拿现成的用(这里就不讲了,别问为什么,因为我不会~)
然后我就想可不可以在打包的时候就把这些依赖文件放到工程中一起包,在请求外部html文件的时候直接加载本地的资源文件,这样除了能提高页面加载速度外还能帮用户节省一定流量。最后在网上找到两位大神的文章:

安卓:http://www.android100.org/html/201502/12/117881.html
iOS:http://www.jianshu.com/p/2ed92d399b4b/comments/4668793

感谢两位大神的指导,现学现用;首先在安卓项目中,我找到加载外部html文件的webView Java类,重写其中一个方法(转:API 11(HONEYCOMB)提供的shouldInterceptRequest(WebView view, String url) 函数来加载本地资源。在API 21又将这个方法弃用了,是重载一个新的shouldInterceptRequest,需要的参数中将url替换成了成了request),直接上代码:

//如果本地有某些文件,则直接从本地读取,不从网络加载
            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
                WebResourceResponse response = null;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
                    response = super.shouldInterceptRequest(view, url);
                    if (url.contains("3.15/init.js")){
                        try {
                            response = new WebResourceResponse("application/x-javascript", "UTF-8", X5ctx.getAssets().open("map/arcgis/init.js"));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (url.contains("css/esri.css")){
                        try {
                            response = new WebResourceResponse("text/css", "UTF-8", X5ctx.getAssets().open("map/arcgis/esri.css"));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (url.contains("js/jquery-2.0.3.min.js")){
                        try {
                            response = new WebResourceResponse("text/css", "UTF-8", X5ctx.getAssets().open("map/js/jquery-2.0.3.min.js"));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
                return  response;
            }
        });

这里就用笨方法了,直接拿字符串和服务器端html文件加载的依赖文件的url进行匹配,html文件依赖:


<link rel="stylesheet" href="https://js.arcgis.com/3.15/esri/css/esri.css">
<script src="https://js.arcgis.com/3.15/init.js">script>
<script type="text/javascript" src="js/jquery-2.0.3.min.js">script>

匹配到后,函数就会找到本地指定路径的一个资源文件生成一个response回复请求,就不需要再到网络中花费流量下载了。

WebResourceResponse函数的第一个参数:”text/css” 就是源文件的MIME类型,MIME_百度百科传送门:http://baike.baidu.com/link?url=-te6FgvC94M2cGKF7uWUgNeDbvuzPIJ1hZeTdgJbhcX0g80t-3lD5fWJ91CQXv2ggVA3pk4s8vcd5EjbZy6CCq

WebResourceResponse函数的第二个参数:”UTF-8” 编码格式,一直在用的这个,就不说了。

WebResourceResponse函数的第三个参数:X5ctx.getAssets().open(“map/arcgis/esri.css”) 这个就要解释下。

public Context X5ctx;

直接声明就都没初始化就直接拿来用了,竟然没出啥问题….(因为没在继承了Context的Activity中重载该方法,所以要在前面加Context的实例调用getAssets方法)

getAssets()方法可以获取AssetManager实例,再用AssetManager的open(“源文件路径”)方法得到输入流InputStream(js、css、img等源文件一定要放到安卓工程目录下的assets文件夹中),最后看到网上说的获取完输入流之后还要调用inputStream.close() 和 AssetManager.close() 方法,我这里没用,貌似也没出啥问题,对这方面不了解,懂这方面的朋友如果看到的话麻烦帮忙解释下。

最后将初始化的WebResourceResponse对象返回给外面的重载方法就大功告成了。

iOS要实现这个相对要繁琐一些,下篇博客再回顾下吧。

你可能感兴趣的:(Android)