全国服务热线:4008-888-888

技术知识

详解android与HTML混和开发设计总结

如今许多的 APP中会嵌套循环HTML5的网页页面,例如常常转变的这些,有1一部分网页页面必须原生态Java与HTML5中的js开展互动实际操作,下面详细介绍1下android中HTML5的应用:

1、有关HTML5种cookie

网页页面中将会会用到 客户信息内容等许多主要参数,能够提早把这些信息内容放到cookie中,能够选用下列方式: 

public static void addCookies(Context context, WebView webView, String url) {
  
  String url=“https://www.xxxx.com/xx/xx/”
          String protocol = "";
          String authority = "";
          try {
              URL urlObj = new URL(url);
              protocol = urlObj.getProtocol();
              authority = urlObj.getAuthority();
         } catch (Exception e) {
             e.printStackTrace();
         }
 
         String ua = webView.getSettings().getUserAgentString();
         webView.getSettings().setUserAgentString(Constant.PROJECT_NAME + "/" + ParamHandler.getVersion(context) + "(" + ua + "; HFWSH)");
 
         if (!TextUtils.isEmpty(url) && !TextUtils.isEmpty(protocol) && !TextUtils.isEmpty(authority)) {
             if (protocol.equals("https") && authority.indexOf("liepin.com") > ⑴) {
                 CookieSyncManager.createInstance(context);
                 CookieManager cookieManager = CookieManager.getInstance();
                 cookieManager.setAcceptCookie(true);
                 try {
                     List<String> data = getCookiesString();
                     if (!ListUtils.isEmpty(data)) {
                         for (String value : data) {
                             cookieManager.setCookie(url, value);
                         }
                     }
                     cookieManager.setCookie(url, "client_id=" + Constant.CLIENT_ID + ";path=/;domain=.XXXX.com");
                     cookieManager.setCookie(url, "appVersion=" + Constant .VERSION + ";path=/;domain=.XXXX.com"); 
             CookieSyncManager.getInstance().sync(); 
         } catch (Exception e) { 
             LogUtils.e("Exception:" + e.getMessage()); 
         } 
       } 
     } 
   }
public List<String> getCookiesString() {
      ArrayList data = new ArrayList();
      this.clearExpired();
      Collection values = this.mCookies.values();
      Iterator var3 = values.iterator();
  
      while(var3.hasNext()) {
          SwiftCookie c = (SwiftCookie)var3.next();
          data.add(c.toCookieString());
     }
 
     return data;
 }

在 mWebView.loadUrl(Url)以前加上cookie,网页页面便可以根据cookie取到相应的主要参数值了。

2、有关js的安全性难题

js在4.2之前有系统漏洞

根据JavaScript,能够浏览当今机器设备的SD卡上面的任何物品,乃至是联络人信息内容,短消息等。好,大家1起看来看是如何出現这样的不正确的。

1,WebView加上了JavaScript目标,而且当今运用具备读写能力SDCard的管理权限,也便是:android.permission.WRITE_EXTERNAL_STORAGE

2,JS中能够遍历window目标,寻找存在“getClass”方式的目标的目标,随后再根据反射面的体制,获得Runtime目标,随后启用静态数据方式来实行1些指令,例如浏览文档的指令.

3,再从实行指令后回到的键入流中获得标识符串,便可以获得文档名的信息内容了。随后想干甚么就干甚么,好风险。关键JS编码以下:

 function execute(cmdArgs)  
  {  
      for (var obj in window) {  
          if ("getClass" in window[obj]) {  
              alert(obj);  
              return  window[obj].getClass().forName("java.lang.Runtime")  
                   .getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);  
          }  
      }  
 }   

处理计划方案:

1,Android 4.2以上的系统软件

在Android 4.2以上的,google作了调整,根据在Java的远程控制方式上面申明1个@JavascriptInterface,以下面编码:

class JsObject {  
    @JavascriptInterface  
    public String toString() { return "injectedObject"; }  
 }  
 webView.addJavascriptInterface(new JsObject(), "injectedObject");  
 webView.loadData("", "text/html", null);  
 webView.loadUrl("javascript:alert(injectedObject.toString())");  

2,Android 4.2下列的系统软件

这个难题较为难处理,但也并不是不可以处理。

最先,大家毫无疑问不可以再启用addJavascriptInterface方式了。有关这个难题,最关键的便是要了解JS恶性事件这1个姿势,JS与Java开展互动大家了解,有下列几种,比prompt, alert等,

这样的姿势都会对应到WebChromeClient类中相应的方式,针对prompt,它对应的方式是onJsPrompt方式,这个方式的申明以下:

public boolean onJsPrompt(WebView view, String url, String message, 
String defaultValue, JsPromptResult result) 

根据这个方式,JS能把信息内容(文字)传送到Java,而Java也能把信息内容(文字)传送到JS中,通告这个思路大家能不可以寻找处理计划方案呢?

历经1番尝试与剖析,寻找1种较为可行的计划方案,请看下面几个小点:

【1】让JS启用1个Javascript方式,这个方式中是启用prompt方式,根据prompt把JS中的信息内容传送过来,这些信息内容应当是大家组成成的1段成心义的文字,将会包括:特殊标志,方式名字,主要参数等。

在onJsPrompt方式中,大家去分析传送过来的文字,获得方式名,主要参数等,再根据反射面体制,启用特定的方式,从而启用到Java目标的方式。

【2】有关回到值,能够根据prompt回到回去,这样便可以把Java中方式的解决結果回到到Js中。

【3】大家必须动态性转化成1段申明Javascript方式的JS脚本制作,根据loadUrl来载入它,从而申请注册到html网页页面中,实际的编码以下:

javascript:(function JsAddJavascriptInterface_(){  
      if (typeof(window.jsInterface)!='undefined') {      
          console.log('window.jsInterface_js_interface_name is exist!!');}   
      else {  
          window.jsInterface = {          
              onButtonClick:function(arg0) {   
                  return prompt('MyApp:'+JSON.stringify({obj:'jsInterface',func:'onButtonClick',args:[arg0]}));  
              },  
                
             onImageClick:function(arg0,arg1,arg2) {   
                 prompt('MyApp:'+JSON.stringify({obj:'jsInterface',func:'onImageClick',args:[arg0,arg1,arg2]}));  
             },  
         };  
     }  
 }  
 )()  

表明:

1,上面编码中的jsInterface便是要申请注册的目标名,它申请注册了两个方式,onButtonClick(arg0)和onImageClick(arg0, arg1, arg2),假如有回到值,就加上上return。

2,prompt中是大家承诺的标识符串,它包括特殊的标志符MyApp:,后边包括了1串JSON标识符串,它包括了方式名,主要参数,目标名等。

3,当JS启用onButtonClick或onImageClick时,就会回调函数到Java层中的onJsPrompt方式,大家再分析出方式名,主要参数,目标名,再反射面启用方式。

4,window.jsInterface这表明在window上申明了1个Js目标,申明方式的方式是:方式名:function(主要参数1,主要参数2)

3、在html5中开展java和js的互动

1)、方式1:

mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(this, "xxx");

随后在当今类中完成下列方式:

@JavascriptInterface
  public void callbackFromH5(final String j) {
    //TODO
  }

callbackFromH5的姓名务必和网页页面中的js方式名1样

Java启用js方式:

mWebView.loadUrl(String.format("javascript:java2js(0)"));//这里是java端启用webview的JS 

js方式名必须和网页页面端1直

2)方式2: 

jsbridge方式(https://github.com/lzyzsd/JsBridge)

Android JsBridge 便是用来在 Android app的原生态 java 编码与 javascript 编码中架设通讯(启用)公路桥梁的輔助专用工具

1 将jsBridge.jar引进到大家的工程项目 

Android Studio:

  repositories {
  // ...
  maven { url "https://jitpack.io" }
  }
  dependencies {
   compile 'com.github.lzyzsd:jsbridge:1.0.4'
  }

2、合理布局文档

<?xml version="1.0" encoding="utf⑻"?>  
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
      android:layout_width="match_parent"  
      android:layout_height="match_parent"  
      android:orientation="vertical" >  
    
      <!-- button 演试Java启用web -->  
      <Button   
          android:id="@+id/button"  
         android:layout_width="match_parent"  
         android:text="@string/button_name"  
         android:layout_height="dp"  
         />  
       
     <!-- 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>  
   
 </LinearLayout>  

3、java编码

//载入服务器网页页面  
          webView.loadUrl("https://www.baidu.com");  
    
          //务必和js同名涵数。  
          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(,));  
             }  
   
         });  
         //仿真模拟客户获得当地部位  
         User user = new User();  
         Location location = new Location();  
         location.address = "xxx";  
         user.location = location;  
         user.name = "Bruce";  
   
         webView.callHandler("functionInJs", new Gson().toJson(user), new CallBackFunction() {  
             @Override  
             public void onCallBack(String data) {  
                 makeText(MainActivity.this, "网页页面在获得你的信息内容", LENGTH_SHORT).show();  
   
             }  
         });  
   
         webView.send("hello");  
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);  
                 }  
   
             });  

js启用

 var str1 = document.getElementById("text1").value;  
           var str2 = document.getElementById("text2").value;  
    
             //启用当地java方式  
             window.WebViewJavascriptBridge.callHandler(  
                 'submitFromWeb'  
                 , {'param': str}  
                 , function(responseData) {  
                     document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData  
                }  
            );  
 
 //申请注册恶性事件监视 
  document.addEventListener(  
                    'WebViewJavascriptBridgeReady'  
                    , function() {  
                        callback(WebViewJavascriptBridge)  
                    },  
                    false  
                );  
 
 //申请注册回调函数涵数,第1次联接时启用 原始化涵数 
 connectWebViewJavascriptBridge(function(bridge) {  
            bridge.init(function(message, responseCallback) {  
                console.log('JS got a message', message);  
                var data = {  
                    'Javascript Responds': 'Wee!'  
                };  
                console.log('JS responding with', data);  
                responseCallback(data);  
            });  
   
            bridge.registerHandler("functionInJs", function(data, responseCallback) {  
                document.getElementById("show").innerHTML = ("data from Java: = " + data);  
                var responseData = "Javascript Says Right back aka!";  
                responseCallback(responseData);  
            });  
        })  

4、有关webView的提升

1、设定WebView 缓存文件方式

private void initWebView() {  
                
              mWebView.getSettings().setJavaScriptEnabled(true);  
              mWebView.getSettings().setRenderPriority(RenderPriority.HIGH);  
              mWebView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);  //设定 缓存文件方式  
              // 打开 DOM storage API 作用  
              mWebView.getSettings().setDomStorageEnabled(true);  
              //打开 database storage API 作用  
              mWebView.getSettings().setDatabaseEnabled(true);   
             String cacheDirPath = getFilesDir().getAbsolutePath()+APP_CACAHE_DIRNAME;  
     //      String cacheDirPath = getCacheDir().getAbsolutePath()+Constant.APP_DB_DIRNAME;  
             Log.i(TAG, "cacheDirPath="+cacheDirPath);  
             //设定数据信息库缓存文件相对路径  
             mWebView.getSettings().setDatabasePath(cacheDirPath);  
             //设定  Application Caches 缓存文件文件目录  
             mWebView.getSettings().setAppCachePath(cacheDirPath);  
             //打开 Application Caches 作用  
             mWebView.getSettings().setAppCacheEnabled(true); 

2、消除缓存文件

/** 
           * 消除WebView缓存文件 
           */  
          public void clearWebViewCache(){  
                
              //清除Webview缓存文件数据信息库  
              try {  
                  deleteDatabase("webview.db");   
                  deleteDatabase("webviewCache.db");  
             } catch (Exception e) {  
                 e.printStackTrace();  
             }  
               
             //WebView 缓存文件文档  
             File appCacheDir = new File(getFilesDir().getAbsolutePath()+APP_CACAHE_DIRNAME);  
             Log.e(TAG, "appCacheDir path="+appCacheDir.getAbsolutePath());  
               
             File webviewCacheDir = new File(getCacheDir().getAbsolutePath()+"/webviewCache");  
             Log.e(TAG, "webviewCacheDir path="+webviewCacheDir.getAbsolutePath());  
               
             //删掉webview 缓存文件文件目录  
             if(webviewCacheDir.exists()){  
                 deleteFile(webviewCacheDir);  
             }  
             //删掉webview 缓存文件 缓存文件文件目录  
             if(appCacheDir.exists()){  
                 deleteFile(appCacheDir);  
             }  
         }  

3、在应用WebView载入网页页面的情况下,有1些固定不动的資源文档如js/css/照片等資源会较为大,假如立即从互联网载入会致使网页页面载入的较为慢,并且会耗费较为多的总流量。因此这些文档应当放在assets里边同app装包。

处理这个难题用到API 11(HONEYCOMB)出示的shouldInterceptRequest(WebView view, String url) 涵数来载入当地資源。

API 21又将这个方式弃用了,是重载1个新的shouldInterceptRequest,必须的主要参数中将url更换变成变成request。

例如有1个照片xxxxx.png,这个照片早已放在了assets中,如今载入了1个外界html,就必须立即把assets里边的照片拿出来载入而不必须再次从互联网获得。自然能够在html里边将照片连接换为file:///android_asset/xxxxx.png,

可是这样这个html就不可以在Android ,ios,WAP中公共了。

webView.setWebViewClient(new WebViewClient() {  
    
              @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("xxxxx.png")){  
                          try {  
                             response = new WebResourceResponse("image/png","UTF⑻",getAssets().open("xxxxx.png"));  
                         } catch (IOException e) {  
                             e.printStackTrace();  
                         }  
                     }  
                 }  
 //                return super.shouldInterceptRequest(view, url);  
                 return  response;  
             }  
   
             @TargetApi(Build.VERSION_CODES.LOLLIPOP)  
             @Override  
             public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {  
                 WebResourceResponse response = null;  
                 response =  super.shouldInterceptRequest(view, request);  
                 if (url.contains("xxxxx.png")){  
                     try {  
                         response = new WebResourceResponse("image/png","UTF-",getAssets().open("xxxxx.png"));  
                     } catch (IOException e) {  
                         e.printStackTrace();  
                     }  
                 }  
                 return response;  
             }  
 }  

以上便是本文的所有內容,期待对大伙儿的学习培训有一定的协助,也期待大伙儿多多适用脚本制作之家。



在线客服

关闭

客户服务热线
4008-888-888


点击这里给我发消息 在线客服

点击这里给我发消息 在线客服