龙空技术网

Android开发:架构师详解Java和JS的交互设计

恒媛百解 594

前言:

目前各位老铁们对“java交互”大体比较注重,同学们都想要学习一些“java交互”的相关文章。那么小编也在网摘上汇集了一些关于“java交互””的相关文章,希望同学们能喜欢,大家快快来学习一下吧!

分享的时候到了,给大家送上干货了,今天教大家一个在Android开发中Java和js的交互设计。希望对大家有所帮助;

在给大家分享之前,这里推荐下我自己建的Android开发技术分享交流平台 :653961128,不管你是小白还是大牛,我都挺欢迎,不定期分享干货,包括2017最新的Android企业案例学习资料和零基础入门教程,欢迎初学和进阶中的小伙伴,大家一起交流学习,共同进步。

WebView的使用

WebView webView= (WebView) findViewById(R.id.webview);webView.loadUrl("");

可以通过将WebView内嵌在App界面中,来装载网页,通过loadUrl,给予一个本地或者远程的地址,程序执行即可装载出我们的界面。这里代码演示的是在assets文件下一个index.html文件,然后通过我们的Webview装载的。

Android中 JS和Java的交互方式

在进行交互之前需要我们对WebView进行设置开启对JS的支持。

WebSettings settings = webView.getSettings();settings.setJavaScriptEnabled(true);

Java调用JS

通过WebView的loadUrl()

通过WebView的evaluateJavascript()

JS调用Java

通过WebView的JavascriptInterface

通过WebViewClient.shouldOverrideUrlLoading(),拦截加载信息

通过WebChromeClient.onConsoleMessage(),拦截控制台信息

通过WebChromeClient.onJsPrompt(),onJsAlert()、onJsConfirm()拦截Web相应弹框的事件

Java调用JS

在Java中调用JS的代码有两种方式,分别为通过 loadurl 和通过 evaluateJavascript.

首先定义了一个html文件,然后将其放置在asset目录下。通过WebView loadUrl 装载。

通过loadUrl来调用JS方法

通过evaluateJavascript来调用JS方法

通过该方法,我们还可以得到JS方法的返回值,来进行值的展示。

这两个方法在开始调用的时候,出现的问题是报出错误信息,错误信息表示调用的JS方法未被定义,问题原因是因为在oncreate或者onResume方法中调用的时候,其JavaScript文件未被完全加载完成,因此出现了该问题,可以通过监听WebView的装载事件延迟调用来解决该问题。

JS调用Java

JavascriptInterface

该种方式由于存在着缺陷,后来被弃用。具体问题将在下面介绍。这里先讲一下其使用的方式。

1.定义和JS相关的交互类和方法,对于方法通过注解进行标注。

2.向WebView添加该JavaScriptInterface,同时为其指定一个名称,该名称将会在JS文件中使用。

3.JS文件

shouldOverrideUrlLoading

在WebViewClient中有一个方法 shouldOverrideUrlLoading,该方法在每次有新的链接跳转的时候,该函数都会被回调,同时传递该次跳转的url,所以我们可以根据自己的需求制定一个url的规则,在这里对于url进行判断,如果是我们协议内的,则进行拦截,解析我们的协议,然后进行相应的方法调用。

onConsoleMessage()

在WebChromeClient中,有一个函数回调,当我们有console消息的时候,该函数就会被回调到。因此,我们可以自己制定规则,然后触发console消息,这个时候该函数就会被回调,回调之后,根据我们的规则进行解析,然后调用我们本地相应的方法。

1.在WebChromeClient中定义相应回调方法的拦截处理

2.JS文件,向控制台输出信息。

onJsPrompt,onJsConfirm, onJsAlert

除了onConsoleMessage的回调之外,WebChromeClient还提供了onJsConfirm,onJsAlert,onJSPrompt等回调,这些在web端有相应的操作的时候,都会被回调到。对于其拦截,要对其中的result做判断和处理,返回值为true,则表示不再执行,如果返回值不是true,则会网页上的操作继续被执行。我们可以通过该种消息的回调来传递一些信息,通过这个信息来实现JS和Java的交互。

对于三种回调的方式,onJsPrompt可以传递一个任意的值给web,而JsConfirm只能传递是否,onJsAlert则不能够传递值,因此为了实现JS和Java的互相调用,onJsPrompt使用是最方便的。

1.JS文件

2.WebChromeClient中做相应的拦截,这里直接按照传递的数据做比对处理,没有做协议的约束和解析,然后返回一个当前的设备类型。

JSBridge的实现

上面分析了JS和Java的交互的方式,但是如果只是通过上述的方式进行通信,必然会使得代码比较臃肿,也难以维护,因此就出现了各种框架来对其进行封装。这里给出一个简单地通信包装。

我们的需求是实现JS和Java的互相调用,比如JS调用了Java的方法,执行完成之后,能够将结果返回,同时使用返回的结果作为JS方法的参数,执行相应的JS方法。这里采取的通信方式是通过对onJsPrompt的拦截解析,然后通过loadUrl的方式执行JS方法。这里分析的是一个简单开源JSBridge的实现。

JSBridge的实现

Java方法处理

对于JS可能会调用到的Java方法,进行集中管理,对于每一个类,可以自定义名称,方便在JS中的调用。可能会被调用到的Java方法,都要进行注册。

除此之外,还提供了一个调用函数,这个函数主要是对传递的数据根据我们制定的协议进行解析,然后从注册的函数中找到所要调用的函数,执行Java函数。

从上面函数执行的语句中,可以看到起传递的参数有WebView,JSonObject和一个Callback。

这里用来给JS调用的Java方法,传递的值都是JsonObject的形式,Callback则是回调相应的JS方法,当我们的Java方法执行完成之后,如果我们需要调用相应的JS方法,我们可以通过callback提供的 apply 方法来传递一些数据。

这里callback的apply方法的实现。

这里将需要传回的数据,传递给JSBridge中的onFinish方法。传递的数据中有一个端口号,通过这个端口号作为标示,来调用相应的方法。

JS方法处理

JS文件提供了两个方法,一个是call一个是finish,分别是web中被调用,另一个是在native中将会被调用,每一个web中调用我们native方法的时候,都会调用js文件中的oncall方法,同时也会传递一个函数作为回调,js文件中会为该次调用随机生成一个端口号,同时将其回调保存在一个内部列表callbacks中,根据协议规则,通过window.promt的方式将相应的调用传递下去。

在WebChromeClient的onJsPrompt方法中便可以得到相应的信息,通过JSBridge方法对回传数据进行相应的调用。

JS中调用Java方法的方式

第一,二个参数表示调用的Java的方法,第三个参数为传递的参数。第四个参数为设置的回调函数。

至此,一个简单的JSBridge实现了,JS只需要通过call方法传递相应的参数即可调用Java方法,Java只需要将待调用方法进行注册即可。

交互中的安全漏洞问题

进几年和WebView远程代码执行相关的漏洞主要有CVE-2012-6336,CVE-2014-1939,CVE-2014-7224, 这些漏洞中最核心的漏洞是CVE-2012-6336,另外两个CVE只是发现了几个默认存在的接口。

CVE-2012-6636

Android API 16.0及之前的版本中存在安全漏洞,该漏洞源于程序没有正确限制使用WebView.addJavascriptInterface方法。远程攻击者可通过使用Java Reflection API利用该漏洞执行任意Java对象的方法

Google Android <= 4.1.2 (API level 16) 受到此漏洞的影响。

CVE-2014-1939

java/android/webkit/BrowserFrame.java 使用addJavascriptInterface API并创建了SearchBoxImpl类的对象。攻击者可通过访问searchBoxJavaBridge_接口利用该漏洞执行任意Java代码。

Google Android <= 4.3.1 受到此漏洞的影响

CVE-2014-7224

香港理工大学的研究人员发现当系统辅助功能中的任意一项服务被开启后,所有由系统提供的WebView都会被加入两个JS objects,分别为是accessibility和accessibilityTraversal。恶意攻击者就可以使用accessibility和accessibilityTraversal这两个Java Bridge来执行远程攻击代码.

Google Android < 4.4 受到此漏洞的影响。

对于上述漏洞,其攻击原理为得到了Java对象,通过反射的方式来执行自己的恶意代码。

解决方案

1.移除掉原有提供的JavaScript接口

2.升级系统API level 17后,只有显示添加 @JavascriptInterface的方法才能被JavaScript调用,这样反射就失去作用了。但对于更低版本则还是会存在,考虑采用其它方案,例如JSBridge实现交互。

标签: #java交互 #javascript java交互