Android webview加载H5相关知识与理解

十一长假回来,开始捣鼓遗留一些问题,由于webview外连接加载缓慢的问题,决定放到本地加载,本来以为很简单的需求但是开始写的时候还是遇到各种问题,连续两天一直不停采坑,这里记录下,避免以后遇到相似问题。

1、Android 加载本地Html ,导致图片资源加载错误

参考:https://www.jianshu.com/p/018cf169386a 

这里的src并没有使用绝对url,而是使用了相对路径。省略了schema(协议)。而html会为这些资源的url补充上缺失的部分。这里甚至可以把host省略,而webview会自动补充schema和host。这个自动补全功能对于前端开发来说是一件好事,这样在迁移代码的时候,不需要做绝对路径的更改。但是在我们的远端加载切换到本地加载的时候,就会出问题

方法1:既然说html的资源相对链接是不能使用的,那么我们前端开发只要将所有的相对url改成绝对url就可以了

方法2:

 String data = HfFileUtil.readAssetsByName(this, "index.html", "UTF-8");
    
 webView.loadDataWithBaseURL("http://localhost", data, "text/html", "UTF-8", null);

 其中第一个入参baseUrl比较关键,根据注释的说法,使用baseUrl作为基础URL。这个基础URL是可以使得加载js和其他相关URL使用相同的策略,同时意味着可以使用以下的schema:'http', 'https', 'ftp', 'ftps', 'about' or 'javascript' 。那么正好满足了现在的需求。同时,如果需要在URL里面加入请求参数,也能在这个参数内不齐。
第二个入参data就是我们的html内容,直接通过读取文件的方式生成String字符串即可。
第三个参数mimeType实际上和http请求的Content-Type具有相同作用,通常填写text/html即可。
第四个参数encoding顾名思义,就是填写整个html的编码格式
第五个参数historyUrl用于给前端加入history参数。

2、Android js 交互问题

这个已经被博客写烂了,不过还是记录下,方面下次使用直接CV

// 设置编码
mWebView.getSettings().setDefaultTextEncodingName("utf-8");
// 支持js
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebChromeClient(new WebChromeClient());
mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
mWebView.setWebViewClient(new WebViewClientDemo());
// 载入 js
mWebView.loadData("", "text/html", null);
mWebView.getSettings().setDomStorageEnabled(true);

mWebView.loadUrl("file:///android_asset/playback/index.html");

class WebViewClientDemo extends WebViewClient {

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        System.out.println("url:" + url);
        // 当打开新链接时,使用当前的 WebView,不会使用系统其他浏览器
        view.loadUrl(url);
        return true;
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        // 在这里执行你想调用的js函数
        //设置本地调用对象及其接口
        mWebView.addJavascriptInterface(new JsObject(), "android");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            String jsonStr = gson.toJson(bean);
            mWebView.evaluateJavascript("javascript:setParams(" + jsonStr + ")", new ValueCallback<String>() {
                @Override
                public void onReceiveValue(String value) {
                    Log.e("-----------执行访问", value);
                }
            });
        }


    }
}

class JsObject {

    @JavascriptInterface
    public void funAndroid() {
        Toast.makeText(mContext, "调用android本地方法funAndroid!", Toast.LENGTH_LONG).show();
    }

}

 3、遇到js中需要访问网络,请注意了,我就是卡到这里一天。

在Andorid7.0之后,对http请求做了限制。如果js中请求连接不是https的,无效。无效。无效。重要的事情说三次。

方法1: 不用说,让前端改呗,但是他们的限制不我们多,如果不好改的话,就需要我们做一些设置了。

方法2:在清单文件中设置Application 中添加

android:networkSecurityConfig="@xml/network_security_config"
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">js中请求的服务器地址</domain>
    </domain-config>
</network-security-config>

这样配置之后,发现项目中访问一些外网的时候遇到问题,

所以需要改成这个样子

<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
            <certificates src="user" />
        </trust-anchors>
    </base-config>
</network-security-config>

 

 

 

OK ,WebView 事情的告一段落,现在开始踩 录屏的坑,文章末尾吐吐槽

Android录屏 录制内置音,需要Android 系统权限,这个权限是不给三方APP开放的

领导让我想办法:我有啥办法可想,要不,我去更改系统层源码,可是这种需要手机Root,你指望所有用户手机让我Root?

然后又说让我给输出的map4加载音轨,录制出来的视频自己合成一遍。我心里有句话 不值当讲不当讲 ——不怕领导需求刁钻,就怕领导懂点技术,就让你实现自己的想法。我们是一款跑步软件,目前还因为跑步途中耗电被系统各种杀死,冻结。现在又为了这个需求让我开线程后台合成视频。我有啥招~我也很绝望。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章