使用Android的WebView控件调用本地代码
需要读者具备一定的相关语言的编程基础。
环境搭建简述
* 打开 http://developer.android.com/ ,下载集成android SDK的 Eclipse版本
* 打开 http://www.java.com/ , 下载最新版本对应的 JDK。注意,是JDK,不是JRE
安装完后,配置好JAVA_HOME路径,打开Eclipse,新建一个 Android Application Project ,直接运行。
如果成功,则会打开一个 Android 模拟器,显示helloworld。
如果上面步骤不成功。。。则要搞到成功为止才能进行下一步。。。
我操作的时候,Eclipse 所带 SDK 版本是 KitKat。相比以前,搭建Android开发环境简单了很多。
打开项目里面的 MainActivity.java 文件。
把下面代码拷贝进去,复盖原来的,重新编译运行一下,就能看到效果。
这是我刚调出来的,比较稳妥的做法,部分代码参考自互联网,代码细节请自行研究,拿去吧,不客气。(Android 2.1 也能通过)
package com.example.appa;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends Activity {
private WebView webview = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);//可要可不要
initWebWiew();
}
@JavascriptInterface
private void initWebWiew() {
if( webview == null )
{
//实例化WebView对象
webview = new WebView(this);
//设置WebView属性,能够执行Javascript脚本
webview.getSettings().setJavaScriptEnabled(true);
//加载第一个页面,页面不能太大
//loadWebsite();//load外网地址
loadLocal();//加载本地
//设置Web视图
setContentView(webview);
}
}
private void loadWebsite() {
//如果页面中链接,如果希望点击链接继续在当前browser中响应,而不是新开Android的系统browser中响应该链接,必须覆盖 webview的WebViewClient对象。
webview.setWebViewClient(
new WebViewClient(){
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
);
webview.loadUrl("http://www.baidu.com/");
}
private Handler mHandler = new Handler();
@JavascriptInterface
private void loadLocal() {
/*
*这是老版本的写法
Object interfaceObject = new Object() {
public void onClickAndroid() {
mHandler.post(
new Runnable() {
public void run() {
webview.loadUrl("javascript:wave()");
}
}
);
}
};
webview.addJavascriptInterface(interfaceObject, "androidCallback");
*/
//android 4.2, JDK1.7后新版本写法
webview.addJavascriptInterface(new JsObject(), "androidCallback");
//这个 onClickAndroid() 和 androidCallback 的命名,就是对应HTML里面的window.androidCallback.onClickAndroid
webview.loadData(tp, "text/html", "utf-8");
}
private class JsObject {
private String param;
@JavascriptInterface
public void onClickAndroid(String p) {
param = p;
mHandler.post(
new Runnable() {
public void run() {
Log.d("dbg", "receive param:" + param);
String s = param + " " + String.valueOf( Math.round( Math.random()*100 ) );
/*
try {
s = URLEncoder.encode(s, "utf-8");
} catch (Exception e) {
s = "Error";
}
*/
//webview.loadData(s, "text/html", "utf-8");
webview.loadUrl("javascript:responseFromAndroid('" + s + "')");
}
}
);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
//如果不做任何处理,浏览网页,点击系统“Back”键,整个Browser会调用finish()而结束自身,如果希望浏览的网 页回退而不是推出浏览器,需要在当前Activity中处理并消费掉该Back事件。
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) {
webview.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
private static final String tp =
"<font color='#FF00FF'><h1>Test</h1></font>" +
"name:<input type='text' id='txtName'/><br>" +
"age:<input type='text' id='txtAge'/><br>" +
"message:<input type='text' id='txtResult' value=''/><br>" +
"<input type='button' id='btnGo' value='go' onClick='onClickA()'/>" +
"<script>" +
"function onClickA() {" +
" var name = document.getElementById('txtName').value;" +
" var age = document.getElementById('txtAge').value;" +
" var s = name + ',' + age;" +
" window.androidCallback.onClickAndroid(s);" +
"}" +
"function responseFromAndroid(s) { " +
"document.getElementById('txtResult').value = s;" +
"}" +
"</script>";
}