cvmachine.com - 申博开户网

查找: 您的方位主页 > 网络频道 > 阅览资讯:Android与HTMl混合开发功用怎样?

Android与HTMl混合开发功用怎样?

2018-06-20 11:07:49 来历:www.cvmachine.com 【

Android与HTMl混合开发功用怎样?

现在许多的 APP中会嵌套HTML5的页面,比方常常改变的等等,有一部分页面需求原生Java与HTML5中的js进行交互操作,下面介绍一下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") > -1) {
         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,WebView增加了JavaScript目标,并且当时运用具有读写SDCard的权限,也便是:android.permission.WRITE_EXTERNAL_STORAGE

2,JS中能够遍历window目标,找到存在“getClass”办法的目标的目标,然后再通过反射的机制,得到Runtime目标,然后调用静态办法来履行一些指令,比方拜访文件的指令.

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的长途办法上面声明一个@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事情这一个动作,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】让JS调用一个Javascript办法,这个办法中是调用prompt办法,通过prompt把JS中的信息传递过来,这些信息应该是咱们组合成的一段有意义的文本,或许包括:特定标识,办法称号,参数等。

在onJsPrompt办法中,咱们去解析传递过来的文本,得到办法名,参数等,再通过反射机制,调用指定的办法,然后调用到Java目标的办法。

【2】关于回来值,能够通过prompt回来回去,这样就能够把Java中办法的处理结果回来到Js中。

【3】咱们需求动态生成一段声明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:,后边包括了一串JSON字符串,它包括了办法名,参数,目标名等。

3,当JS调用onButtonClick或onImageClick时,就会回调到Java层中的onJsPrompt办法,咱们再解分出办法名,参数,目标名,再反射调用办法。

4,window.jsInterface这表明在window上声明晰一个Js目标,声明办法的方式是:办法名:function(参数1,参数2)

3、在html5中进行java和js的交互

1)、办法一:

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

然后在当时类中完成以下办法:

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

callbackFromH5的姓名有必要和网页中的js办法名相同

Java调用js办法:

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

js办法名需求和网页端一向

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-8"?> 
 <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 
        ); 
 
 //注册回调函数,第一次衔接时调用 初始化函数 
 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加载网页的时分,有一些固定的资源文件如js/css/图片等资源会比较大,假如直接从网络加载会导致页面加载的比较慢,并且会耗费比较多的流量。所以这些文件应该放在assets里边同app打包。

处理这个问题用到API 11(HONEYCOMB)供给的shouldInterceptRequest(WebView view, String url) 函数来加载本地资源。

API 21又将这个办法弃用了,是重载一个新的shouldInterceptRequest,需求的参数中将url替换成了成了request。

比方有一个图片xxxxx.png,这个图片现已放在了assets中,现在加载了一个外部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-8",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; 
       } 
 } 

以上便是本文的全部内容,期望对咱们的学习有所协助,也期望咱们多多支撑申博开户。

 

本文地址:http://www.cvmachine.com/a/question/98911.html
Tags: html 详解 Android
修改:申博开户网
关于咱们 | 联络咱们 | 友情链接 | 网站地图 | Sitemap | App | 回来顶部