转:http://blog.csdn.net/zqilu/article/details/17550645
webview实现的原理:在Robotium源码中有个RobotiumWeb.js的JavaScript文件,我们都知道在pc浏览器的地址栏里可以通过输入javascript文件来执行javascript脚本,而在这里我们可以通过调用webview.loadUrl("javascript")方法来执行javascript脚本。具体实现如下;
首先我们在WebUtil.Java类中使用getJavaScriptAsString()方法读取javascript文件
private String getJavaScriptAsString() {
InputStream fis = getClass().getResourceAsStream("RobotiumWeb.js");
StringBuffer javaScript = new StringBuffer();
try {
BufferedReader input = new BufferedReader(new InputStreamReader(fis));
String line = null;
while (( line = input.readLine()) != null){
javaScript.append(line);
javaScript.append("\n");
}
input.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
return javaScript.toString();
}
然后通过executeJavaScriptFunction()方法执行javascript脚本
private boolean executeJavaScriptFunction(final String function){
final WebView webView = viewFetcher.getFreshestView(viewFetcher.getCurrentViews(WebView.class));
if(webView == null){
return false;
}
final String javaScript = prepareForStartOfJavascriptExecution();
activityUtils.getCurrentActivity(false).runOnUiThread(new Runnable() {
public void run() {
if(webView != null){
webView.loadUrl("javascript:" + javaScript + function);
}
}
});
return true;
}
那么如何把javascript脚本的执行结果返回给Robotium的呢
我们先看一个javascript中的function:
function promptElement(element) {
var id = element.id;
var text = element.innerText;
if(text.trim().length == 0){
text = element.value;
}
var name = element.getAttribute('name');
var className = element.className;
var tagName = element.tagName;
var attributes = "";
var htmlAttributes = element.attributes;
for (var i = 0, htmlAttribute; htmlAttribute = htmlAttributes[i]; i++){
attributes += htmlAttribute.name + "::" + htmlAttribute.value;
if (i + 1 < htmlAttributes.length) {
attributes += "#$";
}
}
var rect = element.getBoundingClientRect();
if(rect.width > 0 && rect.height > 0 && rect.left >= 0 && rect.top >= 0){
prompt(id + ';,' + text + ';,' + name + ";," + className + ";," + tagName + ";," + rect.left + ';,' + rect.top + ';,' + rect.width + ';,' + rect.height + ';,' + attributes);
}
}
从上面的function可以看出最后通过prompt弹出框显示elment的属性信息。
我们知道webview的内核是webkit,在webkit中有两个类协助webview。webviewclient与webchromeclient。
WebViewClient主要帮助WebView处理各种通知、请求事件的
WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等
所以Robotium建立了一个WebChromClient的子类RobotiumWebClient,并重写了 onJsPrompt()方法来接收javascript传回的信息并通过webElementCreator类来存储webview中Element。