欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

移动h5相关

程序员文章站 2022-04-13 17:33:42
...

Native调用js

js
<script type="text/javascript">
      function readyToGo() {
          console.log("111");
          alert("Hello")
      }
      function alertMessage(message) {
          alert(message)
      }
      function getYourCar(){
          return  "Car";
      }
</script>
Native
 //调用 js无参数,无返回值的函数
 mWebView.loadUrl("javascript:readyToGo()");
 //调用有参数、无返回值的函数
 mWebView.loadUrl("javascript:alertMessage(\""+"content"+"\")")
 //调用有返回值的番薯
 mWebView.evaluateJavascript("getYourCar()", new ValueCallback<String>() {
                    @Override
                    public void onReceiveValue(String s) {
                    //返回函数
                        Log.d(TAG, "onReceiveValue: "+s);
                    }
                });

js调用native

  • URL schema方式:
    通过调用WebViewClient的shouldOverrideUrlLoading
    Given the host application a change to take over the control when a new url is      about to be loaded in the current webview
    public boolean shouldOverrideUrlLoding(Webview webview,String url )
    
    如果没有设置WebviewClient,则会通知ActivitManager选择系统默认的浏览器进行处理,
    如果设置了WebviewClient,则会有app内部处理:
    false:默认由Webview处理,webview.load(Url)
    true:由native代码处理,
    • 拦截url跳转
      return true:重写,自己处理,不交给webview处理,用来拦截webview的跳转或者自己处理问题。
      return false:不处理,交由webview自己处理,默认情况
    • 何时调用
      • 网页内点击一个连接
      • 用javascript location.href
      • 但是代码中Webview.loadUrl不会回调
      • tips:post请求不会回调该事件
  • 在webview页面注入原始js代码,addJavaScriptInterface方法实现,
public class JavaBridge {
    @JavascriptInterface
    public String getUserInfo(){
        return "user1";
    }
}
....
mWebView.addJavascriptInterface(new JavaBridge(),"AndroidBridge");
...
 function init(){
        if(AndroidBridge){
           console.log( AndroidBridge.getUserInfo());
        }
 }
  • 4.2以下有安全漏洞,4.2以上修复@JavaScript.
    4.2以下问题处理:WebChromeClient的jsPromp函数,将java的处理结果返回到js。
    另外,在@javaScriptInterface注解的方法里,还可以在判断当前的加载的URL,来进行具体的请求:webview.getUrl() 主线程
@JavascriptInterface
    public void showMessage(final String message) {

        final Activity theActivity = this.activity;
        final WebView theWebView = this.webView;
        this.activity.runOnUiThread(new Runnable() {

            @Override
            public void run() {
                if(!theWebView.getUrl().startsWith("http://tutorials.jenkov.com")){
                    return ;
                }

                Toast toast = Toast.makeText(
                        theActivity.getApplicationContext(),
                        message,
                        Toast.LENGTH_SHORT);

                toast.show();
            }
        });
    }
  • 重写 js里的 alert、prompt、console.log方法,
    在WebviewChromeClient 里面实现回调,分别是:onJsAlert、onJsPrompt、onConsoleMessage
    返回值:false(default),代表不处理,由webview处理;true:代表自己实现逻辑,webview不处理

Webview加载优化

  • 资源本地化
    将一些较重的资源本地化,不常更新的文件
    存:打包时候,打入到apk中;
    取:重写WebViewClient的WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request)方法,通过一定的判别方法(例如正则表达式)拦截相应的请求,从本地读取相应资源并返回;默认返回null;
    更:Cache Control,定期通过api更新本地资源。
    WebSettings settings = webView.getSettings();
    settings.setAppCacheEnabled(true);
    settings.setDatabaseEnabled(true);
    settings.setDomStorageEnabled(true);//开启DOM缓存
    settings.setCacheMode(WebSettings.LOAD_DEFAULT);

浏览器缓存

  • 原理:http协议头,cache-control(Expires)Last-Modified

    1. cache-control:控制文本在本地缓存的时间
      
    2. Expires字段:与Cache-Control功能相同,即控制缓存的有效时间
    3. Last-Modified标志文件在服务器上的最新更新时间
      

    缓存过期后,浏览器使用last-modified-since字段带上last-modified。服务器比较时间戳来判断文件是否有修改。没有修改返回304,继续使用缓存。否则200,返回最新文件
    4.Etag,标识文件在服务器上的最新更新时间。Etag 的取值是一个对文件进行标识的特征字串
    常见用法:

      *     Cache-Control与 Last-Modified 一起使用
      *   Expires与 Etag一起使用;
    

Application Cache 缓存机制

  • 以文件为单位进行缓存,且文件有一定更新机制
  • AppCache 原理有两个关键点:manifest 属性和 manifest 文件

Dom Storage缓存机制

  • localstorage key-value,持久性,清除浏览器缓存后localStorage会被删除,单个domin 5M限制
  • sessionStorage 临时性,页面关闭后无法使用

Web SQL

IndexedDB

支持多种数据格式化,持久化存储、支持事务、游标、索引等数据库操作,空间大 50-250M

  • 应用场景:LBS应用中,需要将latlng转化为地理位置,会通过高德api进行地理位置逆转码,返回一个比较大的json结构,可把他缓存下来,减少http请求,将latlng作为索引,
const $DB = {
    init() {
        let _this = this;
        let req = indexedDB.open("hb_geocode");
        req.onupgradeneeded = e => {
            let db = req.result;
            /* 
              createObjectStore 相当于创建一个表
              "geo" 相当于表名
              keyPath 索引 primary key 
            */
            let obStore = db.createObjectStore("geo", {
                keyPath: "latlng"
            });  

            // 下面这一段相当于创建表的一些数据结构
            obStore.createIndex("address", "address", { unique: false });
            obStore.createIndex("province", "province", { unique: false });
            obStore.createIndex("district", "district", { unique: false });
            obStore.createIndex("street", "street", { unique: false });
            req.result.close();
        };
    },
    /*
       由于indexDB的操作为异步操作,因此用Promise对象进行包装    一下
    */
    Add(payload) {
        return new Promise((resolve, reject) => {
            let db = indexedDB.open("hb_geocode");
          /* 
              
          */
            db.onsuccess = () => {
                db.result
                    .transaction("geo", "readwrite")
                    .objectStore("geo")
                    .add(payload);
                db.result.close();
                resolve();
            };
            db.onerror = e => {
                reject(e);
            };
        });
    },
    Get(key) {
        return new Promise((resolve, reject) => {
            let db = indexedDB.open("hb_geocode");
            db.onsuccess = () => {
                let req = db.result
                    .transaction("geo", "readonly")
                    .objectStore("geo")
                    .get(key);
                db.result.close();

                req.onsuccess = e => {
                    resolve(e.target.result);
                };
                req.onerror = err => {
                    reject(err);
                };
            };
            db.onerror = e => {
                reject(e);
            };
        });
    }
}
相关标签: h5