随着H5的使用越来越广泛,逐渐替换App原生的页面。有的商城类App甚至1/4或1/3都是用网页做的,所以有的App会有频繁的与网页交互。我曾经有个做Android的同事,项目经理说给一个月的期限不会写H5就走人,可见H5的重要性了。
效果请看大屏幕:
如上四个按钮操作分别为:
- Android调用Js方法
- Android调用Js方法并传参
- Js调用Android方法
- Js调用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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.androidusejs.MainActivity"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android模块"
android:textColor="#000"
android:textStyle="bold"
android:textSize="18sp"/>
<TextView
android:id="@+id/tv_androidcalljs"
android:layout_width="170dp"
android:layout_height="30dp"
android:text="Android调用Js"
android:background="@drawable/roundsmall_bggreen"
android:gravity="center"
android:layout_marginTop="10dp"
android:textColor="@color/white"/>
<TextView
android:id="@+id/tv_androidcalljsargs"
android:layout_width="170dp"
android:layout_height="30dp"
android:text="Android调用Js并传参数"
android:background="@drawable/roundsmall_bggreen"
android:gravity="center"
android:layout_marginTop="10dp"
android:textColor="@color/white"/>
<TextView
android:id="@+id/tv_showmsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="调用Android显示结果"
android:textColor="#000"
android:layout_marginTop="20dp"
android:textSize="20sp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
截取预览图为:
2. 在main下创建assets资源文件,并创建html.html文件,项目路径如下图:
3. 给Webview写最最简单的html页面,body里面2个按钮,javascript里面有2个插入文本的function
<html>
<head>
<meta http-equiv="Content-Type" charset="GB2312"/>
<script type="text/javascript">
function javacalljs(){
document.getElementById("showmsg").innerHTML = "JAVA调用了JS的无参函数";
}
function javacalljswith(arg){
document.getElementById("showmsg").innerHTML = (arg);
}
</script>
</head>
<body>
<h3>Web模块</h3>
<h3 id="showmsg">调用js显示结果</h3>
<input type="button" value="Js调用Java代码" onclick="window.android.jsCallAndroid()"/>
<input type="button" value="Js调用Java代码并传参数" onclick="window.android.jsCallAndroidArgs('Js传过来的参数')"/>
</body>
</html>
在浏览器中预览一下:
4. 给WebView加入设置:
WebSettings webSettings = webview.getSettings();
//与js交互必须设置
webSettings.setJavaScriptEnabled(true);
webview.loadUrl("file:///android_asset/html.html");
webview.addJavascriptInterface(MainActivity.this,"android");
理解:
- webSettings.setJavaScriptEnabled(true) 表示让WebView支持调用Js;
- webview.loadUrl("file:///android_asset/html.html") 表示加载assets文件下的html.html文件(因为没有网络地址所以加载的本地文件)
- webview.addJavascriptInterface(MainActivity.this,"android") 给webview添加Js调用接口,第一个参数为类对象,第二个参数为自定义别名,Js通过这个别名来调用Java的方法,我这里自定义为android。
html中用到:<input type="button" value="Js调用Java代码" onclick="window.android.jsCallAndroid()"/>
5. Android调用Js代码,javacalljs()为javascript代码中的一个方法。
tvJs.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
webview.loadUrl("javascript:javacalljs()");
}
});
如上html中代码,向id为showmsg的h3大小标题中写入字符串
function javacalljs(){
document.getElementById("showmsg").innerHTML = "JAVA调用了JS的无参函数";
}
同理,Android调用Js代并传参数
webview.loadUrl("javascript:javacalljswith(" + "'Android传过来的参数'" + ")");
6. Js调用Android方法和传参数
点击html按钮,通过onclick="window.android.jsCallAndroid()事件,通过android别名调用Java文件的jsCallAndroid()方法。曾经Js可直接调用Java代码窃取App信息,为安全起见,在Android4.4以上并且必须加入@JavascriptInterface才有响应。
@JavascriptInterface
public void jsCallAndroid(){
tvShowmsg.setText("Js调用Android方法");
}
@JavascriptInterface
public void jsCallAndroidArgs(String args){
tvShowmsg.setText(args);
}
MainActivity完整代码:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private WebView webview;
private TextView tvJs;
private TextView tvJsArgs;
private TextView tvShowmsg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setWebview();
initView();
}
private void initView() {
tvJs = (TextView) findViewById(R.id.tv_androidcalljs);
tvJsArgs = (TextView) findViewById(R.id.tv_androidcalljsargs);
tvShowmsg = (TextView) findViewById(R.id.tv_showmsg);
tvJs.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
webview.loadUrl("javascript:javacalljs()");
}
});
tvJsArgs.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
webview.loadUrl("javascript:javacalljswith(" + "'Android传过来的参数'" + ")");
}
});
}
private void setWebview() {
webview = (WebView) findViewById(R.id.webview);
WebSettings webSettings = webview.getSettings();
webSettings.setBuiltInZoomControls(true);
webSettings.setSupportZoom(true);
//与js交互必须设置
webSettings.setJavaScriptEnabled(true);
webview.loadUrl("file:///android_asset/html.html");
webview.addJavascriptInterface(MainActivity.this,"android");
}
@JavascriptInterface
public void jsCallAndroid(){
tvShowmsg.setText("Js调用Android方法");
}
@JavascriptInterface
public void jsCallAndroidArgs(String args){
tvShowmsg.setText(args);
}
}
打完收工,还不太明白的童鞋可以下载代码来看并运行测试。