研究混合开发,关键技术是java和js的方法互调,现在采用JavascriptInterface接口很方便,一段时间,解决不了的事返回值的问题。js调用java可以轻松拿到返回值,但是java调用js使用的是webview的loadurl(),这个方法拿不到返回值。搜到的资料也很少。多番琢磨,尝试采用会话的模式,java向js发出数据请求,调用js的一个方法,js在这个方法中反向调用java的一个方法,并把需要的数据作为参数传递过来。通过尝试,此法可行。
下面是代码:
一、Android代码
1.布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.devin.javacalljavascriptdemo.MainActivity">
<Button
android:id="@+id/btn_get_data_from_js"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取网页的数据" />
<TextView
android:id="@+id/tv_info"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<WebView
android:id="@+id/web_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
2.封装进行互调的Object子类
public class JavaObj extends Object {
private Activity mActivity;
private WebView mWebView;
private TextView tvInfo;
public JavaObj(Activity activity, WebView mWebView) {
this.mActivity = activity;
this.mWebView = mWebView;
}
/**
* html中的JavaScript调用Java方法
* 注解是必须的
*
* @return
*/
@JavascriptInterface
public String jsCallJava() {
return "JavaScript调用Java方法";
}
/**
* html中的JavaScript调用带参数的Java方法
* 注解是必须的
*
* @return
*/
@JavascriptInterface
public String jsCallJavaWithParams(String var) {
Toast.makeText(mActivity, var, Toast.LENGTH_SHORT).show();
return "JavaScript调用带参数的Java方法" + var;
}
/**
* java调用html中的方法
*/
@JavascriptInterface
public void javaCallJavaScript() {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mWebView.loadUrl("javascript:show()");
}
});
}
/**
* java调用html中的方法,并且传递参数
*/
@JavascriptInterface
public void javaCallJavaScriptWithParams() {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mWebView.loadUrl("javascript:showWithParam('baoge')");
}
});
}
/**
* java调用html中的方法,从js获取一个数据,显示在文本框中.这需要两个方法配合
*/
@JavascriptInterface
public void javaGetDataFromJs() {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mWebView.loadUrl("javascript:sendData()");
}
});
}
/**
* 配合上面
*/
@JavascriptInterface
public String jsSendDataToJava(String var) {
tvInfo.setText(var);
return "JavaScript收到请求后发送给Java的数据就是:" + var;
}
/**
* js调用Java中的方法,获取一个数据(包名)
*/
@JavascriptInterface
public String jsGetDataFromJava() {
return mActivity.getPackageName();
}
public void setTvInfo(TextView tvInfo) {
this.tvInfo = tvInfo;
}
}
3.主类
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String url = "http://192.168.1.101:8080/index.jsp";
private WebView mWebView;
private Button btnGetData;
private TextView info;
private JavaObj javaObj;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
mWebView = (WebView) findViewById(R.id.web_main);
btnGetData = (Button) findViewById(R.id.btn_get_data_from_js);
info = (TextView) findViewById(R.id.tv_info);
btnGetData.setOnClickListener(this);
WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setDefaultTextEncodingName("utf-8");
mWebView.loadUrl(url);
mWebView.setWebViewClient(new WebViewClient());
//这两句是必须的,"javaObj"就是jsp中调用方法时window后面的对象
javaObj = new JavaObj(this, mWebView);
javaObj.setTvInfo(info);//通信,回调,传引用都可以
mWebView.addJavascriptInterface(javaObj, "javaObj");
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_get_data_from_js:
javaObj.javaGetDataFromJs();
break;
default:
break;
}
}
}
<%@ page language="java" pageEncoding="UTF-8" %>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>js和android相互调用</title>
<head>
<script type="text/javascript" language="javascript">
//调用java方法jsCallJava()
function showHtmlcallJava() {
var str = window.javaObj.jsCallJava();
document.getElementById("info1").value = str;
}
//调用java方法jsCallJavaWithParams(String var),带参数
function showHtmlcallJava2() {
var str = window.javaObj.jsCallJavaWithParams("Devin Chen");
document.getElementById("info2").value = str;
}
//提供给java调用的方法
function show() {
document.getElementById("id_input").value = "Java调用Html中的方法";
}
//提供给java调用的方法,带参数
function showWithParam(param) {
document.getElementById("id_input2").value = "Java调用Html中的方法: " + param;
}
//收到java的数据请求之后,反过来调用java的另一个方法,发送给java数据
function sendData() {
var data = window.javaObj.jsSendDataToJava("这就是我从JavaScript要的数据");
}
function getDataFromJava() {
var packageName = window.javaObj.jsGetDataFromJava();
document.getElementById("info3").value = packageName;
}
</script>
</head>
<body>
<input id="info1" style="width: 90%" type="text" value="null"/><br>
<input type="button" value="Html调用Java方法" οnclick="showHtmlcallJava()"/><br>
<input id="info2" style="width: 90%" type="text" value="null"/><br>
<input type="button" value="Html调用带参数的Java方法" οnclick="showHtmlcallJava2()"/><br>
<input id="id_input" style="width: 90%" type="text" value="null"/><br>
<input type="button" value="Java调用Html方法" οnclick="window.javaObj.javaCallJavaScript()"/><br>
<input id="id_input2" style="width: 90%" type="text" value="null"/><br>
<input type="button" value="Java调用带参数的Html方法" οnclick="window.javaObj.javaCallJavaScriptWithParams()"/><br>
<input id="info3" style="width: 90%" type="text" value="null"/><br>
<input type="button" value="调用Java方法获取包名" οnclick="getDataFromJava()"/>
</body>
</html>
运行结果: