Android WebView 和 javaScript的互相调用(三)
原文出處:http://motalks.cn/2016/08/27/Android-WebView-JavaScript-2/
WebView相關閱讀
- Android WebView 和 javaScript的互相調用(一)
- Android WebView 和 javaScript的互相調用(二)
- Android WebView 和 javaScript的互相調用(三)
- Android WebView與js交互通信
- Android 4.4 中 WebView 使用注意事項
- Android WebView開發問題匯總
- Android WebView 性能優化
一、Demo動圖演示
動圖鎮樓,演示功能點的順序是:5-1-2-3-4
二、怎么生成我們需要的 HTML 頁面?
當我們get了WebView 和 JavaScript交互的技能時,準備躍躍欲試的時候,就會對這個被這個問題搞懵逼了,他娘的我又不是前端,要我立馬寫個自己想要的HTML頁面臣妾真的辦不到啊。
三、w3school是什么?
是什么?你咋不點進去看看呢?
四、我們需要的 HTML 頁面
按照w3school的簡單教程我們就可以拼湊出我們所需要的頁面了,如下圖。
五、我們要實現的5個功能
- Android Native 端調用 HTML 中的 javascript 腳本
- Android Native 端調用 HTML 中的 javascript 腳本并傳遞參數
- HTML 中的 javascript 腳本調用 Android Native 端的函數
- HTML 中的 javascript 腳本調用Android Native 端的函數并傳遞參數
- HTML 中的 javascript 腳本與 Android Native端的 Java 代碼完整交互流程
1、Android Native 端調用 HTML 中的 js 腳本
該例子中Android Native 端的 java 代碼會直接調用 HTML 頁面中的js 腳本,實現更改 HTML 頁面 subtitle 的功能。
Android Native 端的代碼為:
mCallJsBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mCallJsWithArgsBtn.setText("Native調用WebView的有參JS腳本");mWebView.loadUrl("javascript:changeDemoSubtitle()");}});HTML 對應的 js 方法是:
function changeDemoSubtitle(){ document.getElementById("subtitle").innerHTML="我加了點料"; }2、Android Native 端調用 HTML 中的 js 腳本并傳遞參數
Android Native 端的代碼為:
mCallJsWithArgsBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mCallJsWithArgsBtn.setText("參數為:" + showDevInfo());showDevInfoToH5();}});private String showDevInfo() {return "showDevInfo('手機型號:" + android.os.Build.MODEL +",SDK版本:" + android.os.Build.VERSION.SDK +",系統版本:" + android.os.Build.VERSION.RELEASE + "')"; }private void showDevInfoToH5() {mWebView.loadUrl("javascript:" + showDevInfo()); }HTML 對應的 js 方法是:
function showDevInfo(info){ document.getElementById("subtitle").innerHTML=info; }3、HTML 中的 javascript 腳本調用 Android Native 端的函數
HTML 對應的 js 方法是:
function disp_confirm(){confirm(); }Android Native 端的代碼為:
mWebView.setWebChromeClient(new WebChromeClient() {@Overridepublic boolean onJsConfirm(WebView view, String url, String message, JsResult result) {Toast.makeText(MainActivity2.this, "Android_Native_Toast!", Toast.LENGTH_SHORT).show();}result.confirm();return true;}});4、HTML 中的 javascript 腳本調用Android Native 端的函數并傳遞參數
HTML 對應的 js 方法是:
function disp_confirm_with_args(message){confirm(message);}Android Native 端的代碼為:
mWebView.setWebChromeClient(new WebChromeClient() {@Overridepublic boolean onJsConfirm(WebView view, String url, String message, JsResult result) {Toast.makeText(MainActivity2.this, "Android_Native_Toast!接收到的參數message:" + message, Toast.LENGTH_SHORT).show();}result.confirm();return true;}});5、HTML 中的 javascript 腳本與 Android Native端的 Java 代碼完整交互流程
HTML 對應的 js 方法是:
function disp_confirm_with_args(message){confirm(message);}<input type="button" onclick="disp_confirm_with_args('getDevInfo')" value="點擊獲取用戶手機信息"/>Android Native 端的代碼為:
mWebView.setWebChromeClient(new WebChromeClient() {@Overridepublic boolean onJsConfirm(WebView view, String url, String message, JsResult result) {if ("getDevInfo".equals(message)) {showDevInfoToH5();} }result.confirm();return true;}});private String showDevInfo() {return "showDevInfo('手機型號:" + android.os.Build.MODEL +",SDK版本:" + android.os.Build.VERSION.SDK +",系統版本:" + android.os.Build.VERSION.RELEASE + "')"; }private void showDevInfoToH5() {mWebView.loadUrl("javascript:" + showDevInfo()); }Android Native 端代碼完整展示:
Activity 代碼:
public class MainActivity2 extends Activity {private WebView mWebView; private Button mCallJsBtn; private Button mCallJsWithArgsBtn;@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main_2);initView();initWebView(); }private void initView() {mWebView = (WebView) findViewById(R.id.webview);mCallJsBtn = (Button) findViewById(R.id.call_js_without_args_btn);mCallJsWithArgsBtn = (Button) findViewById(R.id.call_js_with_args_btn);mCallJsBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mCallJsWithArgsBtn.setText("Native調用WebView的有參JS腳本");mWebView.loadUrl("javascript:changeDemoSubtitle()");}});mCallJsWithArgsBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mCallJsWithArgsBtn.setText("參數為:" + showDevInfo());showDevInfoToH5();}}); }private void initWebView() {//開啟JavaScript功能mWebView.getSettings().setJavaScriptEnabled(true);//加載本地htmlmWebView.loadUrl("file:///android_asset/JsDemo.html");mWebView.setWebChromeClient(new WebChromeClient() {@Overridepublic boolean onJsConfirm(WebView view, String url, String message, JsResult result) {if ("getDevInfo".equals(message)) {showDevInfoToH5();} else if (TextUtils.isEmpty(message)) {Toast.makeText(MainActivity2.this, "Android_Native_Toast!", Toast.LENGTH_SHORT).show();} else {Toast.makeText(MainActivity2.this, "Android_Native_Toast!接收到的參數message:" + message, Toast.LENGTH_SHORT).show();}//回調通知H5頁面用戶操作已完成,可以再次點擊相關按鈕result.confirm();//設為true,可以消耗掉H5頁面的confirm彈窗。return true;}}); }private String showDevInfo() {return "showDevInfo('手機型號:" + android.os.Build.MODEL +",SDK版本:" + android.os.Build.VERSION.SDK +",系統版本:" + android.os.Build.VERSION.RELEASE + "')"; }private void showDevInfoToH5() {mWebView.loadUrl("javascript:" + showDevInfo());} }XML 代碼
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayout android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#000000"android:orientation="vertical"><TextView android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="10dp"android:paddingBottom="10dp"android:paddingTop="10dp"android:text="Android_Native"android:textColor="#FFFFFF" /><Button android:id="@+id/call_js_without_args_btn"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="10dp"android:text="Native調用WebView的JS腳本" /><Button android:id="@+id/call_js_with_args_btn"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="10dp"android:paddingBottom="10dp"android:paddingTop="10dp"android:text="Native調用WebView的有參JS腳本" /> </LinearLayout><WebView android:id="@+id/webview"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#FFFFFF"/> </LinearLayout>AndroidManifest 文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="cn.mtalks.jsbridgedemo"><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:supportsRtl="true"android:theme="@style/AppTheme"><activityandroid:name=".MainActivity2"android:label="@string/app_name"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application> </manifest>友情提示
其實在JavaScript調用 Java本地方法,谷歌官方的實現方法應該是使用 JavascriptInterface 方式。但是該方式在 Android4.2版本之前存在安全漏洞,感興趣的看這里。在Android4.2版本之后加入了@JavascriptInterface注解才得以解決,考慮到目前 Android 版本碎片化太嚴重,使用JavascriptInterface并不適合,這也是上篇文章沒把它放入效率對比的原因。
以上就是一個完整的 WebView 與 JavaScript 的交互例子。大家可以自己動手試試上篇文章介紹的ShouldInterceptRequest方式來實現這個例子。
總結
以上是生活随笔為你收集整理的Android WebView 和 javaScript的互相调用(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RecyclerView优秀文集
- 下一篇: Android WebView 性能优化