Android面試一天一題(Day 23:當(dāng)Android遇上JavaScript)

前幾天面試一個高級工程師,他有多年的Android開發(fā)經(jīng)驗(yàn),同一應(yīng)用也常常負(fù)責(zé)做IOS的版本,后端人力不夠時也去幫忙改改BUG,在小公司里人很容易被訓(xùn)練成多面手。在談到混合開發(fā)時,他說之前還用過PhoneGap進(jìn)行過開發(fā),那么我很自然地就問他:“你對現(xiàn)在比較流行的React Native怎么看呢?”

結(jié)果他一臉茫然,不知React Native為何物。在確認(rèn)不是他聽錯的情況后,我對他的看法就改變了,我認(rèn)為對于目前的移動端開發(fā)來說,沒用過React Native并不可恥,但是沒聽說過的話就很沒臉混了。

所以,這一題我們來談?wù)勗贏ndroid中遇到JavaScript的問題。

面試題:Android中Java和JavaScript如何交互?

先說一些基礎(chǔ)的知識,而JavaScript 是一種腳本語言,個人認(rèn)為他比Java更面像對象,它沒有編譯、鏈接等操作,在運(yùn)行時才動態(tài)的進(jìn)行詞法、語法分析,生成抽象語法樹和字節(jié)碼,然后由解釋器負(fù)責(zé)執(zhí)行或者使用 JIT 將字節(jié)碼轉(zhuǎn)化為機(jī)器碼再執(zhí)行。整個流程由 JavaScript 引擎負(fù)責(zé)完成,在Android手機(jī)上,這個JavaScript 引擎就是WebView的實(shí)現(xiàn)內(nèi)核。

在Android 4.4版本中,原本基于Android WebKit的WebView實(shí)現(xiàn)被換成基于Chromium的WebView實(shí)現(xiàn)。

在Android應(yīng)用中我們可以通過WebView從url加載網(wǎng)頁,很多公司在面試時也會考查一下面試者是否有Java和JavaScript交互的經(jīng)驗(yàn)。這里我們也簡單說一下,Java和JavaScript交互主要分為:

1、Java調(diào)用WebView加載的網(wǎng)頁上的JavaScript

在Java端可以通過WebView調(diào)用JavaScript,基本格式為:

webView.loadUrl(“javascript:methodName(parameterValues)”)

有時還要注意這個javascript:methodName是有參數(shù)還是無參數(shù),有返回值的情況也會有所不同,畢竟我們從webView.loadUrl的接口看不到如何處理返回值。Android 4.4之后WebView增加了evaluateJavascript接口可以供我們通過ValueCallback這個回調(diào)處理返回值。

public void evaluateJavascript(String script, ValueCallback<String> resultCallback)

在4.4之前的版本,常用的思路是Java調(diào)用JavaScript方法,JavaScript方法執(zhí)行完畢,再次調(diào)用Java代碼將值返回。

2、JavaScript調(diào)用本地的Java對像方法

JavaScript調(diào)用Java需要在WebView通過addJavascriptInterface添加一個實(shí)例到WebView的一個Map對象中,也就是下面接口中第一個參數(shù)。

public void addJavascriptInterface(Object object, String name)

調(diào)用格式為window.?name.methodName(parameterValues),methodName為object實(shí)例提供的方法。在Android 4.2之后引入了@JavascriptInterface,被標(biāo)為JavascriptInterface的方法才能在JavaScript端進(jìn)行調(diào)用,也就是說在4.2之前的版本開放JavaScript調(diào)用Java實(shí)例的功能是有全安隱患的。

因?yàn)镴avaScript端調(diào)用Java時是通過反射的方式??梢栽贘avaScript端通過window.?name.getClass().forName反射調(diào)用java.lang.Runtime類的方法(getRuntime),之后便可以執(zhí)行一些命令做些壞事情了。

所以在4.2之前的版本一般都建議:

關(guān)閉JavaScript功能(setJavaScriptEnabled);
不使用addJavascriptInterface;
用removeJavascriptInterface移除系統(tǒng)自帶的實(shí)例(如:WebView默認(rèn)會addJavascriptInterface添加一個 “searchBoxJavaBridge_” 的實(shí)例)。

如果非要在4.2之前的版本使用JavaScript功能,那該怎么辦呢?這個問題我也沒有很好的答案,你可以試試問問面試者,看看他們的想法。

混合開發(fā)(Hybrid App)的問題

人都是向往懶和舒服的,當(dāng)我們針對同一業(yè)務(wù)需求要開發(fā)多個版本的移動端應(yīng)用時,我們很容易想到能不能像JAVA一樣只寫一次代碼在各個平臺都可以運(yùn)行,所以就產(chǎn)生了一種叫Hybrid App(混合應(yīng)用)開發(fā)方式。

簡單地說,原來一個項(xiàng)目我們一般要做Web、Android和IOS三個應(yīng)用,現(xiàn)在我們做混合應(yīng)用,用CSS,HTML和JavaScript編寫應(yīng)用,在Android和IOS上用Webview做為載體來運(yùn)行。很多開源庫也為我們寫為了JavaScript調(diào)用原生模塊的接口供我們調(diào)用。只要我們的HTML界面看起來像手機(jī)自帶的控件,那么理論上用戶是區(qū)分不開是原生的應(yīng)用還是Web應(yīng)用,而且可以動態(tài)部署的優(yōu)點(diǎn)也很吸引人。

但理想是豐滿的,現(xiàn)實(shí)總是那么殘酷。

性能問題首當(dāng)其沖,IOS的手機(jī)要好些,但在硬件標(biāo)準(zhǔn)參差不齊的Android設(shè)備上,使用Webview加載和渲染JavaScript的性能較差,稍微復(fù)雜一點(diǎn)或CSS動畫多一些,卡頓現(xiàn)象就很常見了。

而且兼容性問題也很突出,包括Android官方的WebView實(shí)現(xiàn)內(nèi)核都發(fā)生了變化,每個版本所支持的功能也有不同。再加上ROM廠商亂改系統(tǒng)自帶的WebView,從而導(dǎo)致在各種小細(xì)節(jié)上不同手機(jī)的顯示效果或運(yùn)算結(jié)果不同。

安全問題和調(diào)試難的問題也不容忽視,最終發(fā)現(xiàn)解決它們成本并不比原生開發(fā)的成本低。之前Facebook也想使用H5來做移動應(yīng)用,后來也無法解決這些問題,最終放棄了,所以才有了今天的React Native。

React Native

正如項(xiàng)目的名字那樣,React Native的目的是構(gòu)建真正native的應(yīng)用。而不是構(gòu)建在Webview里運(yùn)行的混合模式的應(yīng)用,開發(fā)完全由JavaScript和React來完成。簡單說它的原理就是,開發(fā)用JavaScript開發(fā)Web的方式進(jìn)行開發(fā),最終在移動端會使用一個JavascriptCore解釋器引擎來解析JS相關(guān)文件成相應(yīng)的原生控件再進(jìn)行渲染,性能上得到了很大的提升。

FaceBook開發(fā)React是對以前思維模式進(jìn)行了改變,不再追求一次編寫到處運(yùn)行,而是轉(zhuǎn)而探討:

Learn once,Write anywhere!

小結(jié)

前端的發(fā)展如火如荼,而且從業(yè)人數(shù)不可小覷,目前高端的前端開發(fā)的薪資待遇方面都很不錯,也說明了市場對它的認(rèn)可。雖然目前看,前端開發(fā)還有些混亂(開發(fā)框架和模式琳瑯滿目),難度和復(fù)雜度也在增加,但并不能排除它一統(tǒng)天下的可能性。

做為Android的工程師,你無法確認(rèn)Androd或者IOS會不會走Symbian(Nokia用的平臺)的老路,這樣看來,接觸一些前端開發(fā)知識,對我們來說是很有必要的。這也是為什么我會因?yàn)橐粋€高級工程師不知道React Native而改變對他的看法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容