大家都知道,通过WebView,我们可以在Android客户端,用Web开发的方式来开发我们的应用。
如果一个应用就是单纯一个WebView,所有的逻辑都只需要在网页上交互的话,那我们其实就只需要通过html和javascript来跟服务器交互就可以了。
但是很多情况下,我们的应用不是单纯一个WebView就可以了,有可能会需要运用到Android本身的应用,比如拍照,就需要调用Android本身的照像机等,要产生震动,在需要运用到手机特性的一些场景下,肯定需要这么一套机制在javascript和Android之间互相通信,包括同步和异步的方式,而这套机制就是本文中我想要介绍的。
一步一步来,我们先从最简单的地方讲起:
1)需要一个WebView去展现我们的页面,首先定义一个布局,非常简单,就是一个WebView,如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width= "match_parent"
android:layout_height= "match_parent"
android:orientation= "vertical">
<WebView
android:id="@+id/html5_webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
这个WebView就是承载我们页面展现的一个最基本的控件,所有在页面上的逻辑,需要跟Android原生环境交互的逻辑数据都是通过它来传输的。
2)在对应的Activity中,对WebView进行一些初始化
mWebView = (WebView) findViewById(R.id. html5_webview );
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptCanOpenWindowsAutomatically( true );
webSettings.setJavaScriptEnabled( true );
webSettings.setLayoutAlgorithm(LayoutAlgorithm. NORMAL );
mWebView.setWebChromeClient( new WebServerChromeClient());
mWebView.setWebViewClient( new WebServerViewClient());
mWebView.setVerticalScrollBarEnabled( false );
mWebView.requestFocusFromTouch();
mWebView.addJavascriptInterface( new AppJavascriptInterface(), "nintf" );
2.1)webSettings.setJavaScriptEnabled( true );
告诉WebView,让它能够去执行JavaScript语句。在一个交互的网页上,javascript是没办法忽略的。
2.2)mWebView.setWebChromeClient( new WebServerChromeClient());
2.3)mWebView.setWebViewClient( new WebServerViewClient());
WebChromeClient和WebViewClient是WebView应用中的两个最重要的类。
通过这两个类,WebView能够捕获到Html页面中url的加载,javascript的执行等的所有操作,从而能够在Android的原生环境中对这些来自网页上的事件进行判断,解析,然后将对应的处理结果返回给html网页。
这两个类是html页面和Android原生环境交互的基础,所有通过html页面来跟后台交互的操作,都在这两个类里面实现,在后面我们还会详细说明。
2.4)mWebView.addJavascriptInterface( new AppJavascriptInterface(), "nintf" );
这个JavascriptInterface,则是Android原生环境和javascript交互的另一个窗口。
将我们自定义的AppJavascriptInterface类,调用mWebView的addJavascriptInterface方法,可以将这个对象传递给mWebView中Window对象的nintf属性("nintf"这个属性名称是自定义的)之后,
就可以直接在javascript中调