写在前面
话说HTML5和原生代码这个口水仗打了很久了。打口水仗的人多半都是喷口水而已。这其中的奥妙真正干活的人才知道。如果说HTML5能完全代替原生,那要原生干什么?如果说HTML5完全不可用,那这么多牛逼的网站是打脸的么?所以说呢,webview在android和ios就是个控件,你就好好的当他控件来用。webview是一个有完整UI系统和生态系统的控件。用好了那是好处多多的。
好,那么问题来了。作为一个控件,是少不了和原生代码交互的。但是常见的用法似乎只是用来打开一个网页。这个勉强算是 "原生代码 call js", 还是一次性的。但是"js call 原生"要怎么玩呢?我曾经研究过一番,在前人的基础上写了个工具https://github.com/fangj/WebViewJavascriptBridge 但是不太完善。那么有现成的cordova是要用起来的。
在说cordova之前。我大概说一下webview和原生怎么交互的:
- Android
Android->JS : loadUrl
JS->Android: JavascriptInterface
- IOS IOS->JS: loadUrl
JS->IOS: loadUrl, IOS拦截自定义schema
下面正式开始讲:
主要内容都在文档里
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_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)。方法的参数[...]。
- 在IOS里怎么写插件
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="Echo">
<param name="ios-package" value="Echo" />
<param name="onload" value="true" />
</feature>
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,加上这么一句
<feature name="Echo">
<param name="android-package" value="org.apache.cordova.plugin.Echo" />
<param name="onload" value="true" />
</feature>
android-package是android对应的类名。
- 玩起来
现在可以玩起来了。 对于ios.可以打开safari进入开发模式进行调试 对于chrome。可以打开chrome,进入chrome://inspect/ 进行调试。详见:http://www.ituring.com.cn/article/130135http://www.ituring.com.cn/article/130379