前言
之前面试也遇到到这个,现在做邮箱系统也有类似需求,决定好好研究一番!
效果图
什么是JS?
JS:JavaScript的缩写,是个脚本语言,跟Java也没有太大的关系,相对来说,从事前端工作的用的比较多,比如学习过PHP,ASP.NET(我大学的专业)的都要牢牢的掌握,因此我略懂一点,大学看过杨中科老师的.NET视频,视频讲的很好,学习了Dom,JQurey,Ajax等,JQuery其实就是封装了一个JS的函数等可以理解为一个JS的快捷库,对于前端来说,JS是很重要的,我觉得安卓和前端类似,咱们也要学点,毕竟安卓本身也是“混搭”模型,跟网页比较类似,跳来跳去的.
什么是Native?
近几年很火的一个词语啊,ReactNative,H5等都跟Native挂钩。安卓和IOS开发的App就是Native App(原生App),而用RN或者H5开发的app叫做“网页”app,严格意义上来说,不能叫做app,其实就是用网页技术html,js等来开发的,界面效果等各方面比较像原生app而已,网页技术发展比较快,但是替代原生,我觉得还是要走很长一段路的,感觉原生也替代不了,以后也许会有个革新吧,我们拭目以待就是啦!
怎么理解JS和Native交互
1.Native原生调用网页里JS代码块
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script>
function showInfo(content)
{
document.getElementById("info").innerHTML=content;
}
//这个函数来更新id为hrefId的html块,传入参数随意,可以是字符串,数字等
function updateHref(defaultContent){
//这里面我定义了一个对象,对象随意定义了name和age,还可以继续的添加比如性别
var person = new Object();
person.name = defaultContent;
person.age = 11;
document.getElementById("hrefId").innerHTML=person.name + "年龄= " + person.age;
}
</script>
</head>
<body>
Android调用Js的showInfo方法,传的数据为:<span id="info"> </span>
<br>
<a href="#" id="hrefId" οnclick="window.GJNativeAPI.callAndroid('')">
这个就是JS调用Android Native的方法了,传什么值可以由 调用者本身控制
</a>
</body>
</html>
上面是我在assets目录放的一个html文件,符合W3C规范的html文件,上面有些地方是有注释的,JS代码块的风格是以<Script>开头,以</Script>结束,中间是编写JS函数的地方,初始化变量的地方.上面有两个函数,一个是showInfo(content),你一定会问,content是什么鬼,这个我为了“见名知意”,这个参数其实可以是任意类型,可以是字符串或者数字,如果不太懂语法的话,博客最后会有一个链接,大家可以简单学习下JS的函数,语法等,略知一二就行.
2.JS调用原生Native定义好的方法
另一个函数叫updateHref(defaultContent),这个我是为了更新
<a href="#" id="hrefId" οnclick="window.GJNativeAPI.callAndroid('')">
这个就是JS调用Android Native的方法了,传什么值可以由 调用者本身控制
</a>
这块的内容而写的函数,就是效果图中第二个按钮点击后,会弹出SnackBar提示并更新这个链接Href的innerHtml(内容).
具体说下:第一个按钮就是android原生调用了JS的函数showInfo,而这个showInfo就是为id为info的innerHtml 赋值,即内容.
第二个函数,是JS调用Android原生代码里定义的函数callAndroid(String str),看下我代码里的
/**
* 供 js 调用的本地对象
*/
public class GJNativeAPI {
@JavascriptInterface
public void callAndroid(final String str) {
Snackbar.make(getCurrentFocus(), str, Snackbar.LENGTH_SHORT).show();
}
}
然后回过头来看网页中的定义
<a href="#" id="hrefId" οnclick="window.GJNativeAPI.callAndroid('')">
这个就是JS调用Android Native的方法了,传什么值可以由 调用者本身控制
</a>
ID为hrefId的click事件为"window.GJNativeAPI.callAndroid('可以传一个默认内容'),这个事件就是响应了咱们自己定义的事件了,这个就是JS调用原生Native的方法啦.
这个跟网页交互,肯定要有展示网页的控件啦,首先想到的是WebView,IOS是UIWebView,首先Webview需要loadUrl,否则无法进行JS和Native的互相访问.
WebView配置,具体代码如下:
webView.loadUrl(TEST_HTML);
webView.addJavascriptInterface(new GJNativeAPI(), "GJNativeAPI");
webView.setWebViewClient(webViewClient);
完整代码如下:
package com.androidjsnativedemo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
public class WebViewActivity extends AppCompatActivity {
private static final String TEST_HTML = "file:///android_asset/h5.html";
WebView webView;
Button androidHandleJs, jsHandleAndroid;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webview);
initView();
initWebViewConfig();
initData();
initListener();
}
private void initView() {
webView = (WebView) findViewById(R.id.webview);
androidHandleJs = (Button) findViewById(R.id.androidHandleJs);
jsHandleAndroid = (Button) findViewById(R.id.jsHandleAndroid);
}
private void initData() {
webView.loadUrl(TEST_HTML);
webView.addJavascriptInterface(new GJNativeAPI(), "GJNativeAPI");
webView.setWebViewClient(webViewClient);
}
private void initWebViewConfig() {
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
}
private void initListener() {
androidHandleJs.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
webView.loadUrl("javascript:showInfo('Android 调用 JS里的方法,我是来自Android端调用并传数据给你更新Html界面')");
}
});
jsHandleAndroid.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
webView.loadUrl("javascript:window.GJNativeAPI.callAndroid('JS调用Android自定义的Native方法并在Native原生Activity提示')");
webView.loadUrl("javascript:updateHref('更改href的默认内容')");
}
});
webView.setWebViewClient(new WebViewClient());
}
/**
* 供 js 调用的本地对象
*/
public class GJNativeAPI {
@JavascriptInterface
public void callAndroid(final String str) {
Snackbar.make(getCurrentFocus(), str, Snackbar.LENGTH_SHORT).show();
}
}
private WebViewClient webViewClient = new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
webView.loadUrl("javascript:window.GJNativeAPI.callAndroid('JS调用Android自定义的Native方法并在Native原生Activity提示')");
webView.loadUrl("javascript:updateHref('更改href的默认内容')");
}
};
}
大家所看到的webview.loadUrl(javascipt:updateHref)",这些语法等可以到网上学习
点击打开链接 3W学校,很方便,资源很丰富!
每天都努力一点点吧,加油!