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

闲谈Hybrid

程序员文章站 2024-01-02 09:39:34
前言 当经常需要更换样式,产品迭代,那么我们应该考虑hybrid混合开发,上层使用Html&Css&JS做业务开发,底层透明化、上层多多样化,这种场景非常有利于前端介入,非常适合业务快速迭代. webview app有时需要去替换我们app的html、css……,文件非常多,需要我们在app启动的时 ......

前言

当经常需要更换样式,产品迭代,那么我们应该考虑hybrid混合开发,上层使用Html&Css&JS做业务开发,底层透明化、上层多多样化,这种场景非常有利于前端介入,非常适合业务快速迭代.

webview

app有时需要去替换我们app的html、css……,文件非常多,需要我们在app启动的时候从服务器下载zip包,解压,这过程当然也需要进行版本管理,下载前可以进行版本对比,进行版本更新

file协议

通过file://从本地加载

闲谈Hybrid

 Hybrid和H5

  • hybrid开发成本、运营成本相对较高
  • hybrid运行相对流畅、H5还会有短暂的加载
  • hybrid适合产品型、H5适合运营

JS和客户端通信

闲谈Hybrid

WebViewJavascriptBridge

  • 在Android中引用控件
 <!-- webview 演示web调用Java -->  
    <com.github.lzyzsd.jsbridge.BridgeWebView  
        android:id="@+id/webView"  
       android:layout_width="match_parent"  
        android:layout_height="match_parent" >  
     </com.github.lzyzsd.jsbridge.BridgeWebView>  

  

<com.kingdee.k3.scm.wms.core.widget.webview.BridgeWebView
    android:id="@+id/bwv_detail"
    android:layout_width="match_parent"
    android:layout_height="0dip"
    android:layout_weight="1">
</com.kingdee.k3.scm.wms.core.widget.webview.BridgeWebView>

 

  • 加载H5页面

  

//Android向js端发送数据 调用webview callback
 webView.callHandler("functionInJs", "data from Java", new CallBackFunction() {  
  
                @Override  
                public void onCallBack(String data) {  
                    // TODO Auto-generated method stub  
                    Log.i(TAG, "reponse data from js " + data);  
                }  
  
            }); 

  

例如//此时为新增数据
mWebView.callHandler("addBill", mPresenter.getAddNewDataParams(), data -> {
    //发送给客户端成功后
    Timber.i("addDatal", "handler = addData, data from web = " + data);
}); 

  

 

  • js调用Android
js端
//调用本地java方法  
           window.WebViewJavascriptBridge.callHandler(  
               'submitFromWeb'  
               , {'param': str1}  
               , function(responseData) {  
                   document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData  
               }  
           );  

  

android端

 

//必须和js同名函数,注册具体执行函数,类似java实现类。  
        webView.registerHandler("submitFromWeb", new BridgeHandler() {  
  
            @Override  
            public void handler(String data, CallBackFunction function) {  
  
                String str ="这是html返回给java的数据:" + data;  
                // 例如你可以对原始数据进行处理  
                makeText(MainActivity.this, str, LENGTH_SHORT).show();  
  
                Log.i(TAG, "handler = submitFromWeb, data from web = " + data);  
                function.onCallBack( str + ",Java经过处理后截取了一部分:"+ str.substring(0,5));  
            }  
  
        }); 

  

Schema协议

 

weixin://dl/general
weixin://dl/favorites 收藏
weixin://dl/scan 扫一扫
weixin://dl/feedback 反馈
weixin://dl/moments 朋友圈
weixin://dl/settings 设置
weixin://dl/notifications 消息通知设置
weixin://dl/chat 聊天设置
weixin://dl/general 通用设置
weixin://dl/officialaccounts 公众号
weixin://dl/games 游戏
weixin://dl/help 帮助
weixin://dl/feedback 反馈
weixin://dl/profile 个人信息
weixin://dl/features 功能插件

  

模拟扫一扫功能

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" name="viewport" content="width=device-width,user-scalable=1">
    <title>Schema</title>
</head>
<body>
  <button id="btn">扫一扫</button>
  <script type="application/javascript">
      function invokeScan() {
          window['_invoke_scan_callback_'] =function (results) {
              alert(results);
          }
          var iframe=document.createElement('iframe');
          iframe.style.display='none';
          iframe.src='weixin://dl/scan?k1=v1&callback=_invoke_scan_callback_';
          var body =document;
          body.appendChild(iframe);
          setTimeout(function(){
              body.removeChild(iframe);
              iframe=null;
          })
      }
      document.getElementById('btn').addEventListener('click',function(){
          invokeScan();
      })
  </script>
</body>
</html>

简单封装

(function(window){
        function invokeAppShare(data,callback){
            _invoke_app('share',data,callback)
        }
        function invokeAppScan(data,callback){
            _invoke_app('scan',data,callback)
        }
        window.invoke={
            share:invokeAppShare,
            scan:invokeAppScan
        }
        var schema ="ctapp://utils"
        window._invoke_app =function(type,data,callback){
            switch(type){
                case window.invokeType.SHARE:
                    schema= '/'+window.invokeType.SHARE
                    //分享
                    break;
                case window.invokeType.SCAN:
                    //扫码
                    break;
            }
            schema += '?type=app'
            for(var key in data){
                if(data.hasOwnProperty(key)){
                    schema+= '&' +key +'=' +data[key]
                }
            }
            var callbackName='';
            if(typeof callback === 'string'){
                callbackName=callback
            }else{
                callbackName= callback+ Data.now().toString()
                window[callbackName] =callback
            }
            schema+='&callback='+callbackName;
            var iframe=document.createElement('iframe');
            iframe.style.display='none';
            iframe.src=schema;
            var body =document;
            body.appendChild(iframe);
            setTimeout(function(){
                body.removeChild(iframe);
                iframe=null;
            })
        }
    })(window)

  

 window.invokeType={
          SHARE:'share',
          SCAN:'scan'
      }

  调用

document.getElementById('btn').addEventListener('click',function(){
          window.invoke.scan({k1:'v1'},function () {

          });
      })