Ò»¡¢Cordova
ºËÐÄjavaÀà˵Ã÷
CordovaActivity£ºCordova ActivityÈë¿Ú£¬ÒÑʵÏÖPluginManager¡¢WebViewµÄÏà¹Ø³õʼ»¯¹¤×÷,
Ö»Ðè¼Ì³ÐCordovaActivityʵÏÖ×Ô¼ºµÄÒµÎñÐèÇó¡£
PluginManager£º ²å¼þ¹ÜÀíÆ÷
ExposedJsApi £ºjavascriptµ÷ÓÃNative£¬ ͨ¹ý²å¼þ¹ÜÀíÆ÷PluginManager
¸ù¾ÝserviceÕÒµ½¾ßÌåʵÏÖÀà¡£
NativeToJsMessageQueue£ºNativeµ÷ÓÃjavascript£¬Ö÷Òª°üÀ¨ÈýÖÖ·½Ê½£ºloadUrl
¡¢ ÂÖѯ¡¢·´ÉäWebViewCoreÖ´ÐÐjs
¶þ¡¢ Cordova¿ò¼ÜÀàͼ

Èý¡¢Cordova¿ò¼ÜÆô¶¯
µ±ÊµÏÖÁËDroidGap»òÕßCordovaInterface½Ó¿ÚµÄActivityµÄonCreate·½·¨Öе÷ÓÃDroidGapµÄloadUrl·½·¨¼´Æô¶¯ÁËCordova¿ò¼Ü¡£
CordovaÌṩÁËÒ»¸öClass£¨DroidGap extends CordovaActivity£©ºÍÒ»¸öinterface£¨CordovaInterface£©À´ÈÃAndroid¿ª·¢Õß¿ª·¢Cordova¡£
Ò»°ãÇé¿öÏÂʵÏÖDroidGap¼´¿É£¬ÒòΪDroidGapÀàÒѾ×öÁ˺ܶà×¼±¸¹¤×÷£¬¿ÉÒÔ˵DroidGapÀàÊÇCordova¿ò¼ÜµÄÒ»¸öÖØÒª²¿·Ö£»Èç¹ûÔÚ±ØÒªµÄÇé¿öÏÂʵÏÖCordovaInterface½Ó¿Ú£¬ÄÇôÕâ¸öÀàÖкܶàDroidGapµÄ¹¦ÄÜÐèÒª×Ô¼ºÈ¥ÊµÏÖ¡£¼Ì³ÐÁËDroidGap»òÕßCordovaInterfaceµÄActivity¾ÍÊÇÒ»¸ö¶ÀÁ¢µÄCordovaÄ£¿é£¬¶ÀÁ¢µÄCordovaÄ£¿éÖ¸µÄÊÇÿ¸öʵÏÖÁËDroidGap»òÕßCordovaInterface½Ó¿ÚµÄActivity¶¼¶ÔÓ¦Ò»Ì×¶ÀÁ¢µÄWebView£¬Plugin£¬PluginManager£¬Ã»Óй²ÏíµÄ¡£
ÔÚ³õʼ»¯ÍêCordovaWebViewºóµ÷ÓÃCordovaWebView.loadUrl()¡£´ËʱÍê³ÉCordovaµÄÆô¶¯¡£
1.Cordova¹ØÁª¶ÔÏó³õʼ»¯
ÔÚʵÀý»¯CordovaWebViewµÄʱºò, CordovaWebView¶ÔÏó»áÈ¥´´½¨Ò»¸öÊôÓÚµ±Ç°CordovaWebView¶ÔÏóµÄ²å¼þ¹ÜÀíÆ÷PluginManager¶ÔÏó£¬Ò»¸öÏûÏ¢¶ÓÁÐNativeToJsMessageQueue¶ÔÏó£¬Ò»¸öJavascriptInterface¶ÔÏóExposedJsApi£¬²¢½«ExposedJsApi¶ÔÏóÌí¼Óµ½CordovaWebViewÖУ¬JavascriptInterfaceÃû×ÖΪ£º_cordovaNative¡£
2. CordovaµÄJavascriptInterface
ÔÚ´´½¨ExposedJsApiʱÐèÒªCordovaWebViewµÄPluginManager¶ÔÏóºÍNativeToJsMessageQueue¶ÔÏó¡£ÒòΪËùÓеÄJS¶ËÓëAndroid
native´úÂë½»»¥¶¼ÊÇͨ¹ýExposedJsApi¶ÔÏóµÄexec·½·¨¡£ÔÚexec·½·¨ÖÐÖ´ÐÐPluginManagerµÄexec·½·¨£¬PluginManagerÈ¥²éÕÒ¾ßÌåµÄPlugin²¢ÊµÀý»¯È»ºóÔÙÖ´ÐÐPluginµÄexecute·½·¨£¬²¢¸ù¾Ýͬ²½±êʶÅжÏÊÇͬ²½·µ»Ø¸øJSÏûÏ¢»¹ÊÇÒì²½¡£ÓÉNativeToJsMessageQueueͳһ¹ÜÀí·µ»Ø¸øJSµÄÏûÏ¢¡£
3. ºÎʱ¼ÓÔØPlugin£¬ÈçºÎ¼ÓÔØ
CordovaÔÚÆô¶¯Ã¿¸öActivityµÄʱºò¶¼»á½«ÅäÖÃÎļþÖеÄËùÓÐplugin¼ÓÔØµ½PluginManager¡£ÄÇôÊÇʲôʱºò½«ÕâЩplugin¼ÓÔØµ½PluginManagerµÄÄØ£¿ÔÚbÖÐ˵ÁË×îºó»áµ÷ÓÃCordovaWebView.loadUrl()£¬¶Ô£¬¾ÍÔÚÕâ¸öʱºò»áÈ¥³õʼ»¯PluginManager²¢¼ÓÔØplugin¡£PluginManagerÔÚ¼ÓÔØpluginµÄʱºò²¢²»ÊÇÂíÉÏʵÀý»¯plugin¶ÔÏ󣬶øÊÇÖ»Êǽ«pluginµÄClassÃû×Ö±£´æµ½Ò»¸öhashmapÖУ¬ÓÃserviceÃû×Ö×÷ΪkeyÖµ¡£
µ±JS¶Ëͨ¹ýJavascriptInterface½Ó¿ÚµÄExposedJsApi¶ÔÏóÇëÇóAndroidʱ£¬PluginManager»á´ÓhashmapÖвéÕÒµ½plugin£¬Èç¹û¸Ãplugin»¹Î´ÊµÀý»¯£¬ÀûÓÃjava·´Éä»úÖÆÊµÀý»¯¸Ãplugin£¬²¢Ö´ÐÐpluginµÄexecute·½·¨¡£
4£®CordovaµÄÊý¾Ý·µ»Ø
CordovaÖÐͨ¹ýexec()º¯ÊýÇëÇóandroid²å¼þ£¬Êý¾ÝµÄ·µ»Ø¿Éͬ²½Ò²¿ÉÒÔÒì²½ÓÚexec()º¯ÊýµÄÇëÇó¡£ÔÚ¿ª·¢android²å¼þµÄʱºò¿ÉÒÔÖØÐ´public
boolean isSynch(String action)·½·¨À´¾ö¶¨ÊÇͬ²½»¹ÊÇÒì²½¡£CordovaÔÚandroid¶ËʹÓÃÁËÒ»¸ö¶ÓÁÐ(NativeToJsMessageQueue)À´×¨ÃŹÜÀí·µ»Ø¸øJSµÄÊý¾Ý¡£
1£©Í¬²½
CordovaÔÚÖ´ÐÐÍêexec()ºó£¬android»áÂíÉÏ·µ»ØÊý¾Ý£¬µ«²»Ò»¶¨¾ÍÊǸôÎÇëÇóµÄÊý¾Ý£¬¿ÉÄÜÊÇÇ°ÃæÄ³´ÎÇëÇóµÄÊý¾Ý£»ÒòΪµ±exec()ÇëÇóµÄ²å¼þÊÇÔÊÐíͬ²½·µ»ØÊý¾ÝµÄÇé¿öÏ£¬CordovaÒ²ÊÇ´ÓNativeToJsMessageQueue¶ÓÁÐÍ·popÍ·Êý¾Ý²¢·µ»Ø¡£È»ºóÔÙ¸ù¾ÝcallbackID·´Ïò²éÕÒij¸öJSÇëÇ󣬲¢½«Êý¾Ý·µ»Ø¸ø¸ÃÇëÇóµÄsuccessº¯Êý¡£
2£©Òì²½
CordovaÔÚÖ´ÐÐÍêexec()ºó²¢²»»áͬ²½µÃµ½Ò»¸ö·µ»ØÊý¾Ý¡£CordovaÔÚÖ´ÐÐexec()µÄͬʱÆô¶¯ÁËÒ»¸öXMLHttpRequest¶ÔÏó·½Ê½»òÕßprompt()º¯Êý·½Ê½µÄÑ»·º¯ÊýÀ´²»Í£µÄÈ¥»ñÈ¡NativeToJsMessageQueue¶ÓÁÐÖеÄÊý¾Ý£¬²¢¸ù¾ÝcallbackID·´Ïò²éÕÒµ½Ïà¶ÔÓ¦µÄJSÇëÇ󣬲¢½«¸ÃÊý¾Ý½»¸øsuccessº¯Êý¡£
×¢£ºCordova¶Ô±¾µØµÄHTMLÎļþ(file:// ¿ªÍ·µÄURL)»òÕßÊÖ»úÉèÖÃÓдúÀíµÄÇé¿öÏÂʹÓÃXMLHttpRequest·½Ê½»ñÈ¡·µ»ØÊý¾Ý£¬ÆäËûÔòʹÓÃprompt()º¯Êý·½Ê½»ñÈ¡·µ»ØÊý¾Ý¡£
5¡¢webView.sendJavascript ·¢Ë͵½js¶ÓÁУ¬onNativeToJsMessageAvailable
¸ºÔðÖ´ÐÐjs.
Native µ÷Óà JS Ö´Ðз½Ê½ÓÐÈýÖÖʵÏÖ LoadUrlBridgeMode¡¢ OnlineEventsBridgeMode¡¢PrivateApiBridgeMode
1¡¢webView.sendJavascript ·¢ËÍjs·½·¨µ½JS¶ÓÁÐ
2¡¢onJsPrompt ·½·¨À¹½Ø£¬»ñÈ¡µ÷Ó÷½Ê½
¡·¡·Èç¹ûÊÇgap_bridge_mode£¬ÔòÖ´ÐÐ appView.exposedJsApi.setNativeToJsBridgeMode(Integer.parseInt(message));
¡·¡·Èç¹ûÊÇgap_poll, ÔòÖ´ÐÐ appView.exposedJsApi.retrieveJsMessages("1".equals(message));
3¡¢µ÷ÓÃsetBridgeMode ·½·¨µ÷ÓÃonNativeToJsMessageAvailable
Ö´ÐÐjavascriptµ÷ÓÃ
ËÄ¡¢Nativeµ÷ÓÃjavascript ·½Ê½£ºNativeToJsMessageQueue
1¡¢loadUrl javascript µ÷Ó÷½Ê½
private class LoadUrlBridgeMode extends BridgeMode
if (url.startsWith("file://") || url.startsWith("javascript:") || Config.isUrlWhiteListed(url)) {
}
|
2¡¢Navitiveʼþ֪ͨjavascriptÂÖѯ»ñÈ¡NavitiveÊý¾Ý
private class OnlineEventsBridgeMode extends BridgeMode |
3¡¢Í¨¹ýJava·´Éä»ñÈ¡webview µÄsendMessage ·½·¨Ö´ÐÐjs£¬ Ö§³Ö Android
3.2.4Ö®ÉÏ(°üº¬)
---¿ÉÒÔ½â¾öloadUrl Òþ²Ø¼üÅ̵ÄÎÊÌ⣺µ±ÄãµÄ½¹µãÔÚÊäÈ룬Èç¹ûÕâͨ¹ýloadUrlµ÷ÓÃjs£¬»áµ¼Ö¼üÅÌÒþ²Ø
private class PrivateApiBridgeMode extends BridgeMode
Field f = webViewClass.getDeclaredField("mProvider");
f.setAccessible(true);
webViewObject = f.get(webView);
webViewClass = webViewObject.getClass();
Field f = webViewClass.getDeclaredField("mWebViewCore");
f.setAccessible(true);
webViewCore = f.get(webViewObject);
if (webViewCore != null) {
sendMessageMethod = webViewCore.getClass().getDeclaredMethod("sendMessage", Message.class);
sendMessageMethod.setAccessible(true);
}
Message execJsMessage = Message.obtain(null, EXECUTE_JS, url);
sendMessageMethod.invoke(webViewCore, execJsMessage);
|
4¡¢Native×¢²ájavascript½Ó¿Ú _cordovaNative
boolean isHoneycomb = (SDK_INT >= Build.VERSION_CODES.HONEYCOMB && SDK_INT
<= Build.VERSION_CODES.HONEYCOMB_MR2);
// Bug being that Java Strings do not get converted to JS strings automatically.
This isn't hard to work-around on the JS side, but it's easier to just use the prompt bridge instead.
if (isHoneycomb || (SDK_INT < Build.VERSION_CODES.GINGERBREAD)) {
Log.i(TAG, "Disabled addJavascriptInterface() bridge since Android version is old.");
return;
} else if (SDK_INT < Build.VERSION_CODES.HONEYCOMB && Build.MANUFACTURER.equals("unknown")) {
// addJavascriptInterface crashes on the 2.3 emulator.
Log.i(TAG, "Disabled addJavascriptInterface() bridge callback due to a bug on the 2.3 emulator");
return;
}
this.addJavascriptInterface(exposedJsApi, "_cordovaNative");
|
|