Android WebView呼叫Javascript填坑記

作為誓死效忠大安卓帝國的程序狗,我一般不寫技術(shù)類文章咳蔚。
  你們翻翻我的文章就會發(fā)現(xiàn)豪嚎,我還真不像技術(shù)流的。
  不過最近搞一個安卓的坑谈火,搞得非常蛋疼侈询,于是打算紀(jì)錄下來。

坑是這樣的:我有一個WebView糯耍,里面有一個寫字區(qū)域扔字,然后我要在寫字的同時呼叫里面的JS。
  在iOS上這事挺容易整的温技,比如這樣(obj-C為例):

NSString *hasRange =
    [self stringByEvaluatingJavaScriptFromString:@"MobileWriter.hasRange()"];

但在大安卓帝國革为,這事就有點(diǎn)蛋疼了。

在KitKat上舵鳞,WebView有個接口名叫evaluateJavascript震檩,從而事情是這樣的:

evaluateJavascript("MobileWriter.hasRange();", resultCallback);

這貨看上去和iOS上差不多,但已經(jīng)有點(diǎn)討厭了:它是Callback機(jī)制的蜓堕,不像iOS上直接拿結(jié)果抛虏。
  但,這還算好的套才,如果不是KitKat迂猴,也就是4.4之前的Android,你連這個接口都沒有背伴,于是只能這樣:

loadUrl("javascript:MobileWriter.hasRange();");

這個就很蛋疼了沸毁,因?yàn)闆]有callback儡率,你必須在JS運(yùn)行結(jié)束后,讓JS去調(diào)用一個指定的對象以清,從而通過這個對象來獲得回調(diào)儿普,比如下面這樣:

(In Java)
addJavascriptInterface(new JavascriptDelegate () {
    @JavascriptInterface
    public void jsCallback (String result) {
        Log.i("Editor", "Blablabla...");
    }
}, "AndroidHost");

(In Javascript)
MobileWriter.hasRange = function () {
    "Blablabla..."
    if (AndroidHost && AndroidHost.jsCallback) {
        AndroidHost.jsCallback('Mission Complete.');
    }
};

看著是不是就很蛋疼?
  但掷倔,這根本不算事眉孩,挺Easy的,只要J-J兩端協(xié)議定好勒葱,這都不叫事兒浪汪。
  麻煩的是下面這個問題:
  每次你在Java端使用loadUrl的時候,在4.4以下的安卓上都會引發(fā)WebView的頁面重新載入事件(而且這個你還沒法通過重載WebViewClient的shouldOverrideUrlLoading方法來阻止)凛虽,從而引發(fā)系統(tǒng)的clearHelpers死遭,這貨則會調(diào)用clearTextEntry并最終調(diào)用到hideSoftKeyboard。
  這個貌似看上去沒什么凯旋,但實(shí)際上卻很糟糕呀潭,因?yàn)檫@會導(dǎo)致兩個問題:

  1. SoftKeyboard會自動消失(hideSoftKeyboard);
  2. Contextual Menu和相關(guān)選區(qū)會自動消失(clearTextEntry)至非。

也就是說钠署,如果你在輸入的時候就要調(diào)用JS的話,那么只要你調(diào)用了JS荒椭,輸入狀態(tài)就自動消失谐鼎,鍵盤沒了,選區(qū)沒了趣惠,你得重新開始選擇狸棍。
  這事就很蛋疼了。
  4.4為什么通過調(diào)用loadUrl來調(diào)用JS不會有這個問題味悄?因?yàn)槿绻阏{(diào)用的是javascript協(xié)議從而也就是調(diào)用js函數(shù)的話草戈,其實(shí)4.4下面走的是上面提到的evaluateJavascrpt,當(dāng)然安全了傍菇。

解決這個問題的方法猾瘸,一個是用反射調(diào)用android.webkit.BrowserFrame.stringByEvaluatingJavaScriptFromString(),這個比較蛋疼丢习。
  另一個,則是設(shè)法通知JS我Java端有事件了淮悼,然后讓JS調(diào)用JavascriptDelegate插入的Delegate對象咐低,并從這個對象獲取當(dāng)前要做的事件,并執(zhí)行袜腥。

第一個方法比較霸氣见擦,直接用反射钉汗,相當(dāng)犀利,但我不確定能否通過安檢(不過國內(nèi)App反正也沒啥檢查鲤屡,應(yīng)該不慌损痰。GoogleAppStore是否允許我這么玩我就不知道了)。
  第二個方法比較溫和酒来,沒這么霸氣卢未,但缺點(diǎn)是你得加一個同步鎖,避免操作不同步導(dǎo)致問題——WebView中的JS是跑在另一根線程上的堰汉,這種頻繁的線程間相互調(diào)用回調(diào)的方法安全性是個問題辽社。
  至于說通知JS應(yīng)該要召喚Delegate的方法嘛,當(dāng)然不能傻傻地用loadUrl了翘鸭。你可以小小地微調(diào)一下WebView的尺寸滴铅,引發(fā)JS端的window.onresize事件,然后就可以讓JS端去調(diào)用Java端了就乓。
  或者另一個比較蛋疼的方法是JS端開一個Timeout甚至Interval汉匙,這個有點(diǎn)網(wǎng)站開發(fā)早期的輪詢了,但個人不建議這么做生蚁,畢竟是手機(jī)端盹兢,畢竟是輪詢,還是要考慮資源消耗的守伸。
  至于說有沒有別的通知手段绎秒,這個暫時沒想到。尼摹。见芹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蠢涝,隨后出現(xiàn)的幾起案子玄呛,更是在濱河造成了極大的恐慌,老刑警劉巖和二,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件徘铝,死亡現(xiàn)場離奇詭異,居然都是意外死亡惯吕,警方通過查閱死者的電腦和手機(jī)惕它,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來废登,“玉大人淹魄,你說我怎么就攤上這事”ぞ啵” “怎么了甲锡?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵兆蕉,是天一觀的道長。 經(jīng)常有香客問我缤沦,道長虎韵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任缸废,我火速辦了婚禮包蓝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘呆奕。我一直安慰自己养晋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布梁钾。 她就那樣靜靜地躺著绳泉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪姆泻。 梳的紋絲不亂的頭發(fā)上零酪,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機(jī)與錄音拇勃,去河邊找鬼四苇。 笑死,一個胖子當(dāng)著我的面吹牛方咆,可吹牛的內(nèi)容都是我干的月腋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼瓣赂,長吁一口氣:“原來是場噩夢啊……” “哼榆骚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起煌集,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤妓肢,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后苫纤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體碉钠,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年卷拘,在試婚紗的時候發(fā)現(xiàn)自己被綠了喊废。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡恭金,死狀恐怖操禀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情横腿,我是刑警寧澤颓屑,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站耿焊,受9級特大地震影響揪惦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜罗侯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一器腋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钩杰,春花似錦纫塌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至避除,卻和暖如春怎披,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瓶摆。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工凉逛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人群井。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓状飞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親书斜。 傳聞我的和親對象是個殘疾皇子诬辈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評論 2 359

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,283評論 25 707
  • 前言 總結(jié) Android WebView 常用的相關(guān)知識點(diǎn),令包含以下干貨內(nèi)容分析:Js注入漏洞菩佑、WebView...
    無名小子的雜貨鋪閱讀 69,824評論 17 169
  • WebView·開車指南 2016-08-31BugDev 北京市東城區(qū)首席Bug布道師開山之作自晰,一整月交通事故血...
    53c021c38a1d閱讀 833評論 0 1
  • WebView·開車指南 目錄 WebView簡介 WebView基本使用 WebView常用方法 WebSett...
    南城的人閱讀 4,751評論 0 19
  • dear leader: 我是運(yùn)維組的譚雁宏,很幸運(yùn)在2016年8月3日入職成為公司的試用期員工稍坯,并擔(dān)任運(yùn)維工程師...
    nicksors閱讀 7,937評論 0 8