Android HyBridge 开发
一、三种App开发方式对比
1. Native App
特点:UI元素、数据内容、逻辑架构都安装在手机终端,导致不可跨平台,每次版本升级都要重新打包。
缺点:无法跨平台、升级麻烦、开发成本高(指跨平台开发成本高)
优点:速度快,用户体验好。
2. Web App
定义:可理解为移动端的网站,将网页部署在服务器上,用户通过各大浏览器来访问。
缺点:页面访问速度慢、用户体验差。
优点:跨平台开发成本低(只需要一个H5开发工程师),版本升级方便(因为网页部署在服务器上,所以只需要在服务器端升级就行。可以在任何支持H5的设备上使用)
3. HyBrid App
结合了Native App和Web App的优点,是未来发展的趋势。
二、WebView
android中用来显示网页的控件,继承自View。在App中使用WebView加载网页的3种方式:
//(1)WebView显示外部网页
webview.loadUrl(“Https://www.baidu.com”);
要设置网络权限,client
//(2)webview加载本地资源
webview.loadUrl(“file:///android_asset/test.html”);
//(3)webview显示html语句
String summary=“
Your scored
192points.”;
webview.loadData(summary,”text/html”,null);
三、WebViewSetting,WebViewClient,WebChromeClient
1. WebViewSetting
管理webview的状态,当webview被创建时会有一组默认设置,通过getter自定义设置。
//是否允许在webview中访问内容型url,默认true
setAllowContentAccess(boolean allow)
//是否允许访问文件true
setAllowFileAccess(boolean allow)
//是否允许访问app缓存,默认false
setAppCacheEnabled(boolean flag)
//设置缓存api的文件路径
setCachePath(String path)
//webview是否允许执行js脚本,默认false
setJavaScriptEnabled(boolean flag)
//webview是否允许缩放,默认true
setSuppotZoom(boolean support)
//允许缩放比例,默认false
setTextZoom(int textZoom)
2.WebViewClient的功能
帮助WebView处理各种通知、请求事件。
//用法
myWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
ToastUtil.toastMsg(MainActivity.this, "开始网页请求了");
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
ToastUtil.toastMsg(MainActivity.this, "网页请求成功了");
}
});
3. WebChromeClient的功能
帮助WebView处理 JavaScript 的对话框、网站图标、网站title、加载进度等。
//用法
myWebView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
// ToastUtil.toastMsg(MainActivity.this,"progress:"+newProgress);
}
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
ToastUtil.toastMsg(MainActivity.this, "title:" + title);
}
});
四、HTML5和JS基础
1.HTML
(1)HTML定义
HTML指的是超文本标记语言 (Hyper Text Markup Language),它不是一种编程语言,而是一种标记语言(markup language), 标记语言是一套标记标签(markup tag),HTML使用标记标签来描述网页。HTML通过Web浏览器读取解释页面内容,并显示出来。
(2)HTML元素
HTML 元素指的是从开始标签(start tag)到结束标签(end tag)的所有代码。
(3)HTML属性
HTML 标签可以拥有属性,属性提供了有关 HTML 元素的更多的信息,
属性总是以名称/值对的形式出现,比如:name="value",
属性总是在 HTML 元素的 开始标签中 规定。 例如:style 属性,它的作用是提供了一种改变所有 HTML 元素的样式的通用方法,我们能够通过使用 style 属性直接将样式添加到 HTML 元素,或者间接地在独立的样式表中(CSS 文件)进行定义。
2.HTML5
(1)HTML5定义
HTML5是最新的HTML标准,是专门为承载丰富的web内容而设计的,并且无需额外插件,拥有新的语义、图形以及多媒体元素。HTML5 提供的新元素和新的API简化了web应用程序的搭建。
HTML5 是跨平台的,被设计为在不同类型的硬件(PC、平板、手机、电视机等等)之上运行。
(2)HTML5 标准允许4中不同的属性语法
(3)HTML5 的一些的新特性
新的语义元素:, , , and
新的表单控件,比如数字、日期、时间、日历和滑块;
强大的图像支持:,
强大的多媒体支持:,;
强大的新 API,比如用本地存储取代 cookie
HTML4中部分元素被删除
3.JavaScript
(1)JavaScript的介绍
JavaScript 是脚本语言,是一种轻量级的编程语言,可插入 HTML 页面的编程代码,插入 HTML 页面后,可由所有的现代浏览器执行。
(2)JavaScript的用法
HTML 中的脚本必须位于 标签之间,脚本可被放置在 HTML 页面的 和 部分中。
//例子:
JavaScript的输出:
// 弹出警告框
window.alert()
//将内容写到 HTML 文档中
document.write()
//写入到 HTML 元素
innerHTML
//写入到浏览器的控制台
console.log()
JavaScript 字面量:
数字字面量,例:3.14 1001 123e5
字符串字面量,例:“Hello world” ‘Hello World’
表达式字面量,例:5+6
数组字面量,例:[40, 100, 1, 5, 25, 10]
对象字面量,例:{firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"}
函数字面量,例:function myFunction(a, b) { return a * b;}
JavaScript变量:
使用关键字var来定义变量, 使用等号来为变量赋值,
var x, length;
JavaScript函数:
function showAlertWithParam(param){
alert(param);
}
function showAlertWithReturn(param){
var result="Return : Android call Js "+param;
return result;
}
五、JsBridg的原理和实现
1.Android调用JS的步骤
//1、设置WebView支持JavaScript
mWebView.getSettings().setJavaScriptEnabled(true);
// 2、添加JS回调接口
mWebView.addJavascriptInterface(object, “interfaceName");
// 3、WebView加载网页,外部网页要添加网络权限
mWebView.loadUrl("file:///android_asset/wx.html");
// 4、WebView通过loadUrl方法调用JS方法
mWebView.loadUrl("javascript:actionFromNative()");
// 5、object中接收JS函数的返回值
2. JavaScript调用Android函数步骤
JavaScript调用Android函数步骤
// 1、设置WebView支持JavaScript
mWebView.getSettings().setJavaScriptEnabled(true);
// 2、添加JS回调接口(addJavascriptInterface 产生安全隐患
mWebView.addJavascriptInterface(object, “InterfaceName");
// 3、WebView加载网页,外部网页要添加网络权限
mWebView.loadUrl("file:///android_asset/wx.html");
// 4、JavaScript通过window对象调用Android函数
Window. InterfaceName.androidFunction();
漏洞:这里向WebView注册了一个叫“InterfaceName”的对象,外部网页可以访问到“InterfaceName”对象
,通过“getClass”方法获取该对象的类型类
,再通过反射机制,得到该类的Runtime对象
,最后调用静态方法执行系统命令获取用户手机里的信息。
漏洞解决办法:
(1)Android4.2以上:用@JavascriptInterface来标记可供JS调用的方法;
@android.webkit.JavascriptInterface//标记这个方法在JavascriptInterface接口中,可以被JS调用
public void jsMethod(String paramFromJs){
ToastUtil.toastMsg(MainActivity.this,paramFromJs);
}
(2)Android4.2以下:自定义JS和Android交互方式,即构造JS和Android沟通的桥梁----JSBridge。
3.JSBridge(Android4.2以下实现JS和Android的安全通信)
JS和Android沟通的桥梁,
JSBridge的位置
(1)Android调用JS方法(ok)
WebView.loadUrl(“JavaScript:function()”)//安全
(2)JS调用Android
WebChormeClient中有三个方法:
onJsAlert(警告框)
onJsConfirm(确认框)
onJsPrompt(提示框)
这三个方法都可以从JS向Android传递消息,警告框和确认框使用频繁不宜用来搭建JsBridge,可以选择提示框来搭建JSBridge,在Android重写onJsPrompt获取获取Js向Android传递的信息,并做处理。这样就实现是JS向Android的通信。
(3)JavaScript向Android的通信协议
参照HTTP URL格式: http://host:port/path?param=value(协议名://主机IP:端口号/参数?参数键值对。)
JSBridge的通信协议格式:
jsbridge://className:callbackAddress/methodName?jsonObj,
协议格式说明:协议名://Java暴露给js的类名:java层执行完成后的回调/方法名?json格式的参数。
//JS和Android通信完整协议格式
jsbridge://className:callbackAddress/methodName?jsonObj
//JS调用Android方法格式
JSBridge.jsCallAndroid(className,methodName,params,callback)
//Android调用JS方法格式
mWebView.loadUrl("javascript:JSBridge.onMethodName(port,jsonObj);");
六、safe-java-js-webview-bridge
1.safe-java-js-webview-bridge介绍
safe-java-js-webview-bridge是GitHub上的一个开源库,
它抛弃使用高风险的addJavascriptInterface方法,对JS和Java相互调用方法进行封装,支持异步回调,方法参数支持JS所有已知的类型,包括number、string、boolean、object、
function,实现了JS和java之间的安全通信。GitHub地址:https://github.com/pedant/safe-java-js-webview-bridge
2.safe-java-js-webview-bridge原理
先在Native端编写本地功能的Java类(如HostJsScope.java),然后在初始化WebviewChromeClient时根据该类反射动态生成JS代码,再将动态生成的JS代码通过WebView.loadUrl触发的onProgressChanged方法注入到webview中,供前端可调用。在前端调用HostJsScope对应的接口,触发webview的onPrompt事件,进而调用本地Java
方法,如果有返回值则调用JsCallback将数据返回前端。
3.safe-java-js-webview-bridge的使用
(1)引入safe-java-js-webview-bridge
//build.gradle(project)
repositories {
mavenCentral()
}
//build.gradle(mudule)
implementation 'cn.pedant.safewebviewbridge:library:1.4'
(2)新建SafeChromeClient继承InjectedChromeClient
import cn.pedant.SafeWebViewBridge.InjectedChromeClient;
public class SafeChromeClient extends InjectedChromeClient {
public SafeChromeClient(String injectedName, Class injectedCls) {
super(injectedName, injectedCls);
}
}
(3)新建一个暴露给JS层的类,类中的方法可供JS调用,方法具有统一的格式:
public static T functionName(WebView webview,Type param1,Type param2 .....){...}
public class HostJsScope {
public static void toast(WebView webView, String message) {
Toast.makeText(webView.getContext(), "String:" + message, Toast.LENGTH_SHORT).show();
}
public static void toast(WebView webView, int message) {
Toast.makeText(webView.getContext(), "int:" + message, Toast.LENGTH_SHORT).show();
}
/**
* 给JS返回值
*/
public static String getTestString(WebView view) {
return "Android WebView";
}
(4)在MainActivity中向js注入接口HostApp
public void onSafeJsBridge(View view) {
webView.getSettings().setJavaScriptEnabled(true);
//给JS注入的接口名是HostApp,对应的类是HostJsScope
webView.setWebChromeClient(new SafeChromeClient("HostApp", HostJsScope.class));
webView.loadUrl("file:///android_asset/webstore.html");
}
(5)js调用Android方法
测试同步回调
测试异步回调
<
---------------------------------------完-------------------------------------------