国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android中實現WebView和JavaScript的互相調用詳解

2019-10-22 18:13:20
字體:
來源:轉載
供稿:網友

前言

很多復雜的UI界面,在Android中需要配合大量xml代碼和java代碼實現,而使用HTML5可以非常輕松的實現出來,而且具有很好的跨平臺特性,讓我們不必為了多個平臺而重寫代碼,H5學習成本也較低,上手快。雖然從目前來說H5在Android系統中的速度可能還欠佳一些,但相信隨著手機的性能不斷的提高,這些問題都會被解決

使用H5開發Android的UI界面,最重要的就是如何實現Js代碼和Java代碼之間的互相調用了

在講解之前,讓我們先把項目跑起來

效果圖:

webview,調用js方法,android

準備好index.html文件,將它放入Android工程下的assets文件夾中:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"  "http://www.w3.org/TR/html4/loose.dtd"><html><head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSTest</title> <script src="app.js"></script></head><body><table border="1" width="100%" id="table" cellspacing="0"> <tr>  <td width="50%" align="center">姓名</td>  <td width="50%" align="center">電話</td> </tr></table><hr><input id="jsinput"><Button onclick="getMessage()">js傳值給Toast</Button></body></html>

JavaScript的代碼我單獨寫在一個js文件中了,把app.js文件也放入assets文件夾中:

function getMessage(){ var message = document.getElementById("jsinput"); contact.showToast(message.value);}function addPerson(persons){ var personObjs = eval(persons); var table = document.getElementById("table"); for(var i=0; i < personObjs.length; i++){  var tr = table.insertRow(table.rows.length);  var td1 = tr.insertCell(0);  td1.align = "center";  var td2 = tr.insertCell(1);  td2.align = "center";  td1.innerHTML = personObjs[i].name;  td2.innerHTML = personObjs[i].phone; }}

最后就是Java代碼

public class MainActivity extends AppCompatActivity { private WebView mWebView; private Button mJsMethodBtn; private JsObject jsobj; @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  mJsMethodBtn = (Button) findViewById(R.id.btn_js_method);  mWebView = (WebView) findViewById(R.id.web_view);  mWebView.loadUrl("file:///android/225515.html">android_asset/index.html");  WebSettings setting = mWebView.getSettings();  setting.setJavaScriptEnabled(true);  setting.setDefaultTextEncodingName("utf-8");  jsobj = new JsObject();  mWebView.addJavascriptInterface(jsobj, "contact");  mJsMethodBtn.setOnClickListener(new View.OnClickListener() {   @Override   public void onClick(View v) {    // 添加一個聯系人    jsobj.addPerson();   }  }); } private class JsObject {  // 此方法被js調用  @JavascriptInterface  public void showToast(String message) {   Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();  }  // 在Web頁面增加一個聯系人  public void addPerson() {   String json = "[{/"name/":/"zwt/",/"phone/":/"15949999999/"}]";   mWebView.loadUrl("javascript:addPerson('" + json + "')");  } } }

還有布局代碼:

<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#EED5B7" android:orientation="vertical"> <WebView  android:id="@+id/web_view"  android:layout_width="match_parent"  android:layout_height="360dp"/> <Button  android:id="@+id/btn_js_method"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:text="調用js方法"/></LinearLayout>

一、JavaScript調用Android中的方法

這里實現的場景是點擊Web頁面中的Button,把input中輸入的數據傳遞給Android系統,并通過Toast顯示出來

對應的js代碼:

function getMessage(){ var message = document.getElementById("jsinput"); contact.showToast(message.value);}

對應的java代碼:

// 此方法被js調用@JavascriptInterfacepublic void showToast(String message) { Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();}

其中的“contact”其實指的就是我們在java代碼中定義的JsObject類

他倆通過以下方法實現綁定:

mWebView.addJavascriptInterface(jsobj, "contact");

第一個參數傳入的是一個java對象,第二參數是指定對應的js里調用該類時需要使用的自定義別名,這個方法的作用就是將一個Java對象和JavaScript聯系起來

這里需要注意個問題,在SDK17以上的版本中,google為了安全考慮,只允許js調用帶有@JavascriptInterface注解的Java方法,所以我們要給被js調用的java方法前加上@JavascriptInterface注解

二、Android調用JavaScript中的方法

用戶點擊Android中的Button控件后,傳一個json數據給JavaScript方法,js解析json數據后添加一個新的聯系人顯示在Web頁面上

對應的js代碼:

function addPerson(persons){ var personObjs = eval(persons); var table = document.getElementById("table"); for(var i=0; i < personObjs.length; i++){  var tr = table.insertRow(table.rows.length);  var td1 = tr.insertCell(0);  td1.align = "center";  var td2 = tr.insertCell(1);  td2.align = "center";  td1.innerHTML = personObjs[i].name;  td2.innerHTML = personObjs[i].phone; }}

對應的java代碼:

// 在Web頁面增加一個聯系人public void addPerson() { String json = "[{/"name/":/"zwt/",/"phone/":/"15949999999/"}]"; mWebView.loadUrl("javascript:addPerson('" + json + "')");}

想要調用JavaScript中的某個方法,使用以下方法的標準格式就可以了:

mWebView.loadUrl("javascript:xxxMethod()");

“xxxMethod()”指的是JavaScript中的某個方法,如需調用其它方法,只要把后面的xxxMethod()替換成js中對應的方法就好

三、常見問題

1.Android與js互調不成功

  • 給WebView的setJavaScriptEnabled方法設置為true,使其允許js代碼執行
  • 在API高于17的版本上,需要被js調用的java方法前加上@JavascriptInterface
  • 檢查js中的別名是否寫錯,調用java方法時類的別名,一定要是mWebView.addJavascriptInterface(jsobj, “contact”);里面定義的別名

2.網頁的alert彈不出

需要重寫WebChromeClient中的onJsAlert()方法

mWebView.setWebChromeClient(new WebChromeClient() { @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) {  return super.onJsAlert(view, url, message, result); }});

如果需要把web頁面的alert彈出框替換成Android的AlertDialog,可以在onJsAlert()方法里進行重寫,并設置return為true

3.Js調用java方法修改UI界面不成功

只要明白這一點:js調用的java方法,其實是運行在另外一個子線程WebViewCoreThread中
測試一下:把以下語句分別放在Activity的onCreate()方法里和被js調用的java方法中

Log.e(TAG, "運行線程name->" + Thread.currentThread().getName());

當onCreate執行時運行的log:

運行線程name->main

當JsObject類中的方法運行時的log:

運行線程name->WebViewCoreThread

很明顯,子線程不允許修改主線程UI,所以我們想通過js調用java代碼直接修改UI界面的做法是不被允許的
如果需要修改,可以通過Handler機制去解決

4.如何讓手機的返回鍵跳到上一個Web頁面

如果不對手機系統的返回鍵進行處理,那么我們按返回鍵會直接關閉當前Activity,而不會回到上一個Web頁面
解決這個問題,我們可以重寫Activity中的onBackPressed()方法:

@Overridepublic void onBackPressed() { super.onBackPressed(); if (mWebView.canGoBack()) {  mWebView.goBack(); } else {  finish(); }}

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 威信县| 隆子县| 新泰市| 林甸县| 枞阳县| 津南区| 达州市| 白朗县| 福清市| 辉南县| 平乐县| 榆社县| 雅安市| 大渡口区| 洪泽县| 天台县| 武义县| 惠安县| 雷州市| 仪征市| 新昌县| 社会| 正安县| 徐闻县| 定边县| 牡丹江市| 宁明县| 新疆| 广宁县| 青田县| 淅川县| 兴安盟| 湖北省| 中卫市| 洛川县| 河北省| 蓝山县| 南宁市| 通许县| 松原市| 南京市|