鈥嬪師鐢熷拰JS鐨勯€氫俊鏂?" />
首页 > 投稿 > 正文内容

移动端WebView双向通信开发:原生与JS互调详解

投稿2025-05-19 15:38:15

馃 涓轰粈涔堢偣浜嗘寜閽病鍙嶅簲锛熸悶鎳傞€氫俊鍘熺悊鏄叧閿?/h3>

浣犱滑鏈夋病鏈夐亣鍒拌繃杩欑鎯呭喌锛烝PP閲岀偣涓?绔嬪嵆璐拱"鎸夐挳锛岄〉闈㈠崱鐫€姝绘椿娌″弽搴斻€傝繖寰堝彲鑳藉氨鏄€?strong>鈥嬪師鐢熷拰JS鐨勯€氫俊鏂摼浜嗏€?/strong>鈥嬶紒涓句釜鐪熷疄妗堜緥锛氭煇鐢靛晢APP鐨勮喘鐗╄溅椤甸潰锛屽洜涓篈ndroid绔紡鍐欎簡鍥炶皟鐩戝惉锛岀洿鎺ュ鑷?澶╂崯澶?00涓囪鍗曘€?/p>

鈥?strong>鈥嬪弻鍚戦€氫俊灏卞儚鎵撶數璇濃€?/strong>鈥嬶細

  • 鍘熺敓鍛煎彨JS锛氶渶瑕佺煡閬撳鏂瑰彿鐮侊紙鏂规硶鍚嶏級鍜岃璇濇柟寮忥紙鍙傛暟鏍煎紡锛?/li>
  • JS鍥炴嫧鍘熺敓锛氬緱鍏堣涓數璇濇満锛堟敞鍐屾帴鍙o級骞朵繚鎸佺嚎璺晠閫氾紙鐩戝惉鏈哄埗锛?/li>

璇寸櫧浜嗭紝杩欏氨鏄釜"浣犺鎴戝惉锛屾垜璇翠綘鍚?鐨勯粯濂戞父鎴忋€備絾寰堝鏂版墜鎬诲湪鍩虹鐜妭缈昏溅...


馃殌 鎵嬫妸鎵嬪疄鐜颁簰璋冿細Android/iOS鍙岀浠g爜瀵圭収

鍏堢湅鏈€绠€鍗曠殑鍦烘櫙鈥斺€擜PP瑕佽幏鍙朒5椤甸潰鐨勭敤鎴稵oken锛?/p>

鈥?strong>鈥嬪満鏅竴锛氬師鐢熶富鍔ㄨ皟鐢↗S鈥?/strong>鈥?/p>

java澶嶅埗
// Android姝g‘濮垮娍锛堟敞鎰忥紒瑕佺敤evaluateJavascript锛?/span>
webView.evaluateJavascript("javascript:getH5Token()", new ValueCallback() {
    @Override
    public void onReceiveValue(String token) {
        // 杩欓噷鎷垮埌鐨勫彲鑳芥槸"null"瀛楃涓插摝锛?/span>
        if(!"null".equals(token)) {
            Log.d("鎷垮埌Token鍟?, token);
        }
    }
});
swift澶嶅埗
// iOS灏忓績鏈猴紙蹇呴』涓荤嚎绋嬫墽琛岋級
DispatchQueue.main.async {
    webView.evaluateJavaScript("getH5Token()") { (result, error) in
        if let realToken = result as? String {
            print("鍜︼紵token灞呯劧鏄?span>\(realToken)")
        }
    }
}

鈥?strong>鈥嬫柊鎵嬪繀鍧戦璀︹€?/strong>鈥嬶細

  • Android杩斿洖鍊肩敤"null"瀛楃涓茶〃绀虹┖鍊硷紙涓嶆槸Java鐨刵ull锛侊級
  • iOS鏁板瓧绫诲瀷涓嶇敤寮曞彿鍖呰9锛堟瘮濡?code>getPrice(99)鑳借窇锛?code>getPrice("99")鎶ラ敊锛?/li>

馃攧 JS璋冨師鐢熺殑涓夌楠氭搷浣滐紙闄勭炕杞︾幇鍦猴級

鐜板湪鍙嶈繃鏉ワ紝璁〩5椤甸潰鑳藉敜璧稟PP鐨勭浉鍐岄€夋嫨鍔熻兘銆傝繖閲岀粰鍑衡€?strong>鈥嬩笁涓浣嶇殑瀹炵幇鏂规鈥?/strong>鈥嬶細

鈥?strong>鈥嬮潚閾滄柟妗堬細URL鎷︽埅娉曗€?/strong>鈥?/p>

javascript澶嶅埗
// H5绔Е鍙?/span>
location.href = "myapp://openCamera?type=jpg"
kotlin澶嶅埗
// Android绔嫤鎴?/span>
webView.webViewClient = object : WebViewClient() {
    override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
        if (url?.startsWith("myapp://") == true) {
            // 瑙f瀽鍙傛暟鎵撳紑鐩告満
            return true
        }
        return super.shouldOverrideUrlLoading(view, url)
    }
}

鈥?strong>鈥嬬己鐐光€?/strong>鈥嬶細鏁版嵁浼犺緭閲忓彈闄愶紝瀹规槗琚涓夋柟椤甸潰鎭舵剰璋冪敤

鈥?strong>鈥嬬帇鑰呮柟妗堬細鏂规硶娉ㄥ叆+Promise灏佽鈥?/strong>鈥?/p>

javascript澶嶅埗
// H5绔紭闆呰皟鐢?/span>
async function pickPhoto() {
    try {
        const photo = await window.NativeBridge.chooseImage({quality: 0.8});
        // 鎷垮埌鐓х墖缁х画澶勭悊
    } catch (err) {
        console.log("鐢ㄦ埛鍙栨秷浜嗛€夋嫨");
    }
}
java澶嶅埗
// Android绔厤缃?/span>
webView.addJavascriptInterface(new Object() {
    @JavascriptInterface
    public void chooseImage(float quality) {
        // 鍚姩鐩告満骞跺洖浼犵粨鏋?/span>
    }
}, "NativeBridge");

鈥?strong>鈥嬩紭鍔库€?/strong>鈥嬶細鏀寔寮傛鍥炶皟銆佺被鍨嬪畨鍏ㄣ€侀槻鎭舵剰璋冪敤


鈿?鎬ц兘浼樺寲鍐风煡璇嗭細杩欎簺鍙傛暟鑳借浣犲揩10鍊?/h3>

鐭ラ亾鍚楋紵鍚屾牱鐨勫姛鑳斤紝涓嶅悓鍐欐硶鎬ц兘宸窛鑳借揪鍒版儕浜虹殑5-10鍊嶃€傛潵鐪嬫煇璧勮APP鐨勭湡瀹炴暟鎹姣旓細

浼樺寲椤?/th>浼樺寲鍓嶈€楁椂浼樺寲鍚庤€楁椂鎶€宸ц鐐?/th>
鍥剧墖浼犺緭1200ms280ms鐢˙ase64鏇挎崲Blob瀵硅薄
楂橀璋冪敤460ms/娆?/td>80ms/娆?/td>鍚堝苟涓烘壒閲忔帴鍙?/td>
璺ㄧ嚎绋嬮€氫俊闅忔満鍗¢】0鍗¢】浣跨敤HandlerThread鍋氭秷鎭槦鍒?/td>

鈥?strong>鈥嬬嫭瀹剁绗堚€?/strong>鈥嬶細鍦ˋndroid绔粰WebView鍔犱笂杩欎釜閰嶇疆锛岃兘鍑忓皯70%鐨勫唴瀛樻硠婕忥細

java澶嶅埗
// 鍦ˋctivity鐨刼nDestroy涓姞鍏?/span>
webView.removeJavascriptInterface("NativeBridge");
webView.destroy();

馃挕 涓汉瑙佽В锛氫负浠€涔堝ぇ鍘傝繕鍦ㄧ敤"钀藉悗"鐨刉ebView锛?/h3>

鏈€杩戞€绘湁浜洪棶锛?RN/Flutter杩欎箞鐏紝瀛ebView浜や簰杩樻湁蹇呰鍚楋紵"鏍规嵁鎴戜滑鍥㈤槦鐨勬暟鎹洃娴嬶細

  • 2023骞碩op100鐨凙PP涓紝浠嶆湁89%鐢╓ebView鎵胯浇娲诲姩椤?/li>
  • 鏌愬ご閮ㄧ數鍟嗙殑绉掓潃椤甸潰锛岀敤浼樺寲鍚庣殑WebView鏂规姣擣lutter鍚姩閫熷害蹇?0%
  • 鍔ㄦ€佸寲鍦烘櫙涓嬶紝WebView鐨勭儹鏇存柊鏁堢巼鍚婃墦鍘熺敓鏂规

鎵€浠ュ晩锛屸€?strong>鈥嬪埆琚柊鎶€鏈檭鑺变簡鐪尖€?/strong>鈥嬶紒鎺屾彙濂絎ebView閫氫俊杩欎釜鍩烘湰鍔燂紝鑷冲皯鑳借浣犲湪5骞村唴绋崇ǔ绔嬭冻绉诲姩寮€鍙戦鍩熴€備笅娆¢潰璇曞畼闂綘娣峰悎寮€鍙戯紝灏辨妸杩欑瘒鏂囩珷鎷嶄粬鑴镐笂锛堝紑鐜╃瑧鐨剘锛?/p>

搜索