話說HTML5和原生代碼這個口水仗打了很久了。打口水仗的人多半都是噴口水而已。這其中的奧妙真正干活的人才知道。如果說HTML5能完全代替原生,那要原生干什麼?如果說HTML5完全不可用,那這麼多牛逼的網站是打臉的麼?所以說呢,webview在android和ios就是個控件,你就好好的當他控件來用。webview是一個有完整UI系統和生態系統的控件。用好了那是好處多多的。
好,那麼問題來了。作為一個控件,是少不了和原生代碼交互的。但是常見的用法似乎只是用來打開一個網頁。這個勉強算是 "原生代碼 call js", 還是一次性的。但是"js call 原生"要怎麼玩呢?我曾經研究過一番,在前人的基礎上寫了個工具https://github.com/fangj/WebViewJavascriptBridge 但是不太完善。那麼有現成的cordova是要用起來的。
在說cordova之前。我大概說一下webview和原生怎麼交互的:
Android->JS : loadUrl
JS->Android: JavascriptInterface
下面正式開始講:
主要內容都在文檔裡
http://cordova.apache.org/docs/en/4.0.0/guide_cli_index.md.html#The%20Command-Line%20Interface
http://cordova.apache.org/docs/en/4.0.0/guide_hybrid_plugins_index.md.html#Plugin%20Development%20Guide
http://cordova.apache.org/docs/en/4.0.0/guide_platforms_android_plugin.md.html
http://cordova.apache.org/docs/en/4.0.0/guide_platforms_ios_plugin.md.html
用命令行工具生成cordova工程
sudo npm install -g cordova
cordova create hello com.example.hello HelloWorld
cd hello
cordova platform add ios
cordova platform add android
cordova build
此時android和ios的工程已經生成,可以用你的IDE打開運行了。
開始寫插件。先看JS裡怎麼調用:
cordova.exec(function(winParam) {},
function(error) {},
"service",
"action",
["firstArgument", "secondArgument", 42, false]);
幾個參數分別是:成功回調。失敗回調。要調用的對象(service)。要調用的方法(action)。方法的參數[...]。
Echo.h
#import "CDVPlugin.h"
@interface Echo : CDVPlugin
- (void)echo:(CDVInvokedUrlCommand*)command;
@end
Echo.m
#import "Echo.h"
@implementation Echo
- (void)echo:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult = nil;
NSString* echo = [command.arguments objectAtIndex:0];
if (echo != nil && [echo length] > 0) {
NSLog(@"ios received %@",echo);
NSLog(@"ios send OK");
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:echo];
} else {
NSLog(@"ios send fail");
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
}
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
@end
還有很關鍵的。在ios工程目錄下找到config.xml,加上這麼一句
feature name是JS中調用的插件名,ios-package的value是IOS中對應的類名。
Android 中插件怎麼玩
Echo.java
package org.apache.cordova.plugin; import android.util.Log; import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaPlugin; import org.json.JSONArray; import org.json.JSONException; /** * Created by fangjian on 14-11-28. */ public class Echo extends CordovaPlugin { @Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { if (action.equals("echo")) { String message = args.getString(0); this.echo(message, callbackContext); return true; } return false; }
}private void echo(String message, CallbackContext callbackContext) { if (message != null && message.length() > 0) { Log.d("cordova plugin", "android sent OK"); callbackContext.success(message); } else { Log.d("cordova plugin", "android sent Fail"); callbackContext.error("Expected one non-empty string argument."); } }
同樣,需要找到Android工程目錄下的config.xml,加上這麼一句
android-package是android對應的類名。