Android和js、H5進行交互數據

Android和H5、Js進行交互調用

Android開發過程中,我們或多或少都會用到webview,使用webview來展示一些經常變動的界面更加方便簡單,也已于維護。另一方面hybrid App開發現在用的也越來越多了。其中native和h5之間的交互更是必不可少的。

具體Android中是如何和h5交互的?或者說Android中是如何和js交互的。

1 Webview加載頁面

我們都知道在android中是通過webview來加載html頁面的。根據html文件所在的位置不同寫法也不同。

例如:加載assets文件夾下的test,html頁面

mWebview.loadUrl("file:///android_asset/test.html")

例如:加載網頁

mWebView.loadUrl("http://www.baidu.com")

如果只是這樣調用webview.loadUrl 加載的話,那么當你點擊頁面中的鏈接的時候,頁面將會在你手機默認的瀏覽器上打開。那如果想要在頁面在App內中打開的話,那么就得設置setWebViewClient:

mWebView.setWebViewClient(new WebViewClient() {

? ? ? ? @Override

? ? ? ? public boolean shouldOverrideUrlLoading(WebView view, String url) {

? ? ? ? ? ? ? ? //我們可以在這里攔截特定的rl請求,然后進行自己要的操作

? ? ? ? ? ? ? ? if (url.equals("file:///android_asset/test2.html")) {

? ? ? ? ? ? ? ? ? ? Log.e(TAG, "shouldOverrideUrlLoading: " + url);

? ? ? ? ? ? ? ? ? ? startActivity(new Intent(MainActivity.this,Main2Activity.class));

? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? //這里我們自己重新加載新的url頁面,防止點擊鏈接跳轉到系統瀏覽器

? ? ? ? ? ? ? ? ? ? mWebView.loadUrl(url);

? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? });

重寫Activity的onBackPressed方法,使得返回按鈕不會關閉當前頁面,而是返回webview上一個歷史頁面。

@Override

? ? public void onBackPressed() {

? ? ? ? if (webView.canGoBack()) {

? ? ? ? ? ? //返回上一個頁

? ? ? ? ? ? webView.goBack();

? ? ? ? ? ? return ;

? ? ? ? }

? ? ? ? super.onBackPressed();

? ? }

二、給webview添加加載新頁面的進度條。

開啟和關閉進度條

webView.setWebViewClient(new WebViewClient() {

? ? ? //重寫頁面打開和結束的監聽。打開時彈出對話框,關閉時隱藏

? ? ? /**

? ? ? * 界面打開的回調

? ? ? */

? ? ? @Override

? ? ? public void onPageStarted(WebView view, String url, Bitmap favicon) {

? ? ? ? ? if (progressDialog != null && progressDialog.isShowing()) {

? ? ? ? ? ? ? progressDialog.dismiss();

? ? ? ? ? }

? ? ? ? ? //彈出對話框

? ? ? ? ? progressDialog = new ProgressDialog(JSActivity.this);

? ? ? ? ? progressDialog.setTitle("提示");

? ? ? ? ? progressDialog.setMessage("軟軟正在拼命加載……");

? ? ? ? ? progressDialog.show();

? ? ? }

? ? ? /**

? ? ? * 界面打開完畢的回調

? ? ? */

? ? ? @Override

? ? ? public void onPageFinished(WebView view, String url) {

? ? ? ? ? //隱藏對話框:不為空,正在顯示。才隱藏關閉

? ? ? ? ? if (progressDialog != null && progressDialog.isShowing()) {

? ? ? ? ? ? ? progressDialog.dismiss();

? ? ? ? ? }

? ? ? }

? });

讓進度條顯示頁面加載進度:

//設置進度條

? ? ? ? //WebChromeClient與webViewClient的區別

? ? ? ? //webViewClient處理偏界面的操作:打開新界面,界面打開,界面打開結束

? ? ? ? //WebChromeClient處理偏js的操作

? ? ? ? webView.setWebChromeClient(new WebChromeClient() {

? ? ? ? ? ? /**

? ? ? ? ? ? * 進度改變的回調

? ? ? ? ? ? * WebView:就是本身

? ? ? ? ? ? * newProgress:即將要顯示的進度

? ? ? ? ? ? */

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onProgressChanged(WebView view, int newProgress) {

? ? ? ? ? ? ? ? if (progressDialog != null && progressDialog.isShowing())

? ? ? ? ? ? ? ? ? ? progressDialog.setMessage("軟軟正在拼命加載……" + newProgress + "%");

? ? ? ? ? ? }

三、android本地通過java調用HTML頁面中的javaScript方法

想要調用js方法那么就必須讓webview支持js的代碼。

//首先設置Webview支持JS代碼

webView.getSettings().setJavaScriptEnabled(true);

若調用的js方法沒有返回值,則可以直接調用mWebView.loadUrl(“javascript:do());其中do是js中的方法;

若有返回值時我們可以調用mwebview,evaluteJavascript方法;

@TargetApi(Build.VERSION_CODES.KITKAT)

? ? public void onSum(View view){

? ? ? ? webView.evaluateJavascript("sum(1,2)", new ValueCallback<String>() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onReceiveValue(String value) {

? ? ? ? ? ? ? ? Toast.makeText(getApplicationContext(),

? ? ? ? ? ? ? ? ? ? ? ? "相加結果:"+value, Toast.LENGTH_SHORT).show();

? ? ? ? ? ? }

? ? ? ? });

? ? }

? ? public void onDoing(View view){

? ? ? ? String msg = "測試";

? ? ? ? webView.loadUrl("javascript:showInfoFromJava('"+msg+"')");

? ? }

對應的js方法

? ? function sum(a,b){

? ? ????return a+b;

? ? }

? ? function showInfoFromJava(){

? ? ????document.getElementById("p").innerHTML="Java成功調的JS方法";

? ? }

四、js調用Android本地java方法

在android 4.2以上可以直接使用@javascriptinterface注解來聲明,下面是在一個本地java方法

public void addJavascriptInterface(Object object, String name);

1 object參數:在object對象里面添加我們想要在Js里面調用的Android方法,下面的代碼中我們調用了showToast方法

2 name參數:這里的name就是我們可以在JS里面調用的對象名稱,對應下面代碼中的JSText

對應的JS代碼

function jsJava(){

? ? ? ? //調用java的方法,頂級對象,java方法

? ? ? ? //可以直接訪問JSTest,這是因為JSTest掛載到js的window對象下了

? ? ? ? JSTest.showToast("我是被JS執行的Android代碼");

? ? }

對應的Java代碼:

//java與js回調,自定義方法

? ? ? ? //1.java調用js

? ? ? ? //2.js調用java

? ? ? ? //首先java暴露接口,供js調用

? ? ? ? /**

? ? ? ? * obj:暴露的要調用的對象

? ? ? ? * interfaceName:對象的映射名稱 ,object的對象名,在js中可以直接調用

? ? ? ? * 在html的js中:JSTest.showToast(msg)

? ? ? ? * 可以直接訪問JSTest,這是因為JSTest掛載到js的window對象下了

? ? ? ? */

? ? ? ? webView.addJavascriptInterface(new Object() {

? ? ? ? ? ? //定義要調用的方法

? ? ? ? ? ? //msg由js調用的時候傳遞

? ? ? ? ? ? @JavascriptInterface

? ? ? ? ? ? public void showToast(String msg) {

? ? ? ? ? ? ? ? Toast.makeText(getApplicationContext(),

? ? ? ? ? ? ? ? ? ? ? ? msg, Toast.LENGTH_SHORT).show();

? ? ? ? ? ? }

? ? ? ? }, "JSTest");

五、重繪alert 、confirm和prompt的彈出效果,并把用戶具體操作結果回調給JS

alert彈窗:

重繪confirm彈窗:

重繪prompt彈窗:

具體代碼:

/**

? ? ? ? ? ? * Webview加載html中有alert()執行的時候,會回調這個方法

? ? ? ? ? ? * url:當前Webview顯示的url

? ? ? ? ? ? * message:alert的參數值

? ? ? ? ? ? * JsResult:java將結果回傳到js中

? ? ? ? ? ? */

? ? ? ? ? ? @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)

? ? ? ? ? ? @Override

? ? ? ? ? ? public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {

? ? ? ? ? ? ? ? AlertDialog.Builder builder = new AlertDialog.Builder(JSActivity.this);

? ? ? ? ? ? ? ? builder.setTitle("提示:看到這個,說明Java成功重寫了Js的Alert方法");

? ? ? ? ? ? ? ? builder.setMessage(message);//這個message就是alert傳遞過來的值

? ? ? ? ? ? ? ? builder.setPositiveButton("確定", new OnClickListener() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void onClick(DialogInterface dialog, int which) {

? ? ? ? ? ? ? ? ? ? ? ? //處理確定按鈕,且通過jsresult傳遞,告訴js點擊的是確定按鈕

? ? ? ? ? ? ? ? ? ? ? ? result.confirm();

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? builder.show();

? ? ? ? ? ? ? ? //自己處理

? ? ? ? ? ? ? ? result.cancel();

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? ? ? /**

? ? ? ? ? ? * Webview加載html中有confirm執行的時候,會回調這個方法

? ? ? ? ? ? * url:當前Webview顯示的url

? ? ? ? ? ? * message:alert的參數值

? ? ? ? ? ? * JsResult:java將結果回傳到js中

? ? ? ? ? ? */

? ? ? ? ? ? @Override

? ? ? ? ? ? public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {

? ? ? ? ? ? ? ? AlertDialog.Builder builder = new AlertDialog.Builder(JSActivity.this);

? ? ? ? ? ? ? ? builder.setTitle("提示:看到這個,說明Java成功重寫了Js的Confirm方法");

? ? ? ? ? ? ? ? builder.setMessage(message);//這個message就是alert傳遞過來的值

? ? ? ? ? ? ? ? builder.setPositiveButton("確定", new OnClickListener() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void onClick(DialogInterface dialog, int which) {

? ? ? ? ? ? ? ? ? ? ? ? //處理確定按鈕,且通過jsresult傳遞,告訴js點擊的是確定按鈕

? ? ? ? ? ? ? ? ? ? ? ? result.confirm();

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? builder.setNegativeButton("取消", new OnClickListener() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void onClick(DialogInterface dialog, int which) {

? ? ? ? ? ? ? ? ? ? ? ? //處理取消按鈕,且通過jsresult傳遞,告訴js點擊的是取消按鈕

? ? ? ? ? ? ? ? ? ? ? ? result.cancel();

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? builder.show();

? ? ? ? ? ? ? ? //自己處理

? ? ? ? ? ? ? ? result.cancel();

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? ? ? /**

? ? ? ? ? ? * Webview加載html中有prompt()執行的時候,會回調這個方法

? ? ? ? ? ? * url:當前Webview顯示的url

? ? ? ? ? ? * message:alert的參數值

? ? ? ? ? ? *defaultValue就是prompt的第二個參數值,輸入框的默認值

? ? ? ? ? ? * JsPromptResult:java將結果重新回傳到js中

? ? ? ? ? ? */

? ? ? ? ? ? @Override

? ? ? ? ? ? public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? final JsPromptResult result) {

? ? ? ? ? ? ? ? AlertDialog.Builder builder = new AlertDialog.Builder(JSActivity.this);

? ? ? ? ? ? ? ? builder.setTitle("提示:看到這個,說明Java成功重寫了Js的Prompt方法");

? ? ? ? ? ? ? ? builder.setMessage(message);//這個message就是alert傳遞過來的值

? ? ? ? ? ? ? ? //添加一個EditText

? ? ? ? ? ? ? ? final EditText editText = new EditText(JSActivity.this);

? ? ? ? ? ? ? ? editText.setText(defaultValue);//這個就是prompt 輸入框的默認值

? ? ? ? ? ? ? ? //添加到對話框

? ? ? ? ? ? ? ? builder.setView(editText);

? ? ? ? ? ? ? ? builder.setPositiveButton("確定", new OnClickListener() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void onClick(DialogInterface dialog, int which) {

? ? ? ? ? ? ? ? ? ? ? ? //獲取edittext的新輸入的值

? ? ? ? ? ? ? ? ? ? ? ? String newValue = editText.getText().toString().trim();

? ? ? ? ? ? ? ? ? ? ? ? //處理確定按鈕了,且過jsresult傳遞,告訴js點擊的是確定按鈕(參數就是輸入框新輸入的值,我們需要回傳到js中)

? ? ? ? ? ? ? ? ? ? ? ? result.confirm(newValue);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? builder.setNegativeButton("取消", new OnClickListener() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void onClick(DialogInterface dialog, int which) {

? ? ? ? ? ? ? ? ? ? ? ? //處理取消按鈕,且過jsresult傳遞,告訴js點擊的是取消按鈕

? ? ? ? ? ? ? ? ? ? ? ? result.cancel();

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? builder.show();

? ? ? ? ? ? ? ? //自己處理

? ? ? ? ? ? ? ? result.cancel();

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? });

效果圖:

界面上方是兩個按鈕,下方是一個webview控件,開啟頁面自動加載url,這里為了方便學習,

我已經寫了一個html文件放置在了Asset文件中,通過 file:///android_asset/test.html 來進行加載。

webview成功加載頁面后,會出現四個新的按鈕,點擊不同的按鈕,會產生不同的效果

asset文件夾下面的test.html文件

<html>

<head>

? ? <meta charset="UTF-8">

? ? <title>Document</title>

? ? <script>

? ? function jsAlert(){

? ? ? ? var r = alert("我是Alert的提示框");

? ? ? ? document.getElementById("p").innerHTML="Java成功調的JS的alert方法";

? ? }

? ? function jsConFirm(){

? ? ? var r = confirm("我是ConFirm的彈出框");

? ? ? if (r == true)

? ? ? {

? ? ? ? document.getElementById("p").innerHTML="用戶點擊了確認按鈕";

? ? ? }else{

? ? ? ? document.getElementById("p").innerHTML="用戶點擊了取消按鈕";

? ? ? }

? ? }

? ? function jsPrompt(){

? ? ? ? //第一個參數是提示

? ? ? ? //第二個參數是默認值

? ? ? ? var r = prompt("請輸入姓名:","小明同學");

? ? ? ? if (r != null)

? ? ? ? {

? ? ? ? document.getElementById("p").innerHTML="用戶輸入的姓名為:"+r;

? ? ? ? }else{

? ? ? ? document.getElementById("p").innerHTML="用戶點擊了取消按鈕";

? ? ? ? }

? ? }

? ? function jsJava(){

? ? ? ? //調用java的方法,頂級對象,java方法

? ? ? ? //可以直接訪問JSTest,這是因為JSTest掛載到js的window對象下了

? ? ? ? JSTest.showToast("我是被JS執行的Android代碼");

? ? }

? ? function sum(a,b){

? ? return a+b;

? ? }

? ? function showInfoFromJava(){

? ? document.getElementById("p").innerHTML="JS方法成功被Java調用";

? ? }

? ? </script>

</head>

<body>

<h3 id="p">界面成功初始化</h3>

<h5 onclick="jsAlert()">調用jsAlert方法</h5>

<input type="button" value="開啟Alert提示框" onclick="jsAlert()"/>

<h5 onclick="jsAlert()">調用jsConFirm方法</h5>

<input type="button" value="開啟ConFirm彈窗" onclick="jsConFirm()"/>

<h5 onclick="jsAlert()">調用jsPrompt方法</h5>

<input type="button" value="開啟Prompt彈窗" onclick="jsPrompt()"/>

<h5 onclick="jsAlert()">調用jsJava方法</h5>

<input type="button" value="調用Java方法" onclick="jsJava()"/>

</body>

</html>

具體的java代碼

public class JSActivity extends AppCompatActivity {

? ? //assets下的文件的test.html所在的絕對路徑

? ? private static final String DEFAULT_URL = "file:///android_asset/test.html";

? ? private WebView webView;

? ? private ProgressDialog progressDialog;//加載界面的菊花

? ? @Override

? ? protected void onCreate(Bundle savedInstanceState) {

? ? ? ? super.onCreate(savedInstanceState);

? ? ? ? setContentView(R.layout.activity_js);

? ? ? ? initView();

? ? ? ? initWebView();

? ? }

? ? /**

? ? * 初始化控件

? ? */

? ? private void initView() {

? ? ? ? webView = (WebView) findViewById(R.id.webView);

? ? ? ? webView.loadUrl(DEFAULT_URL);

? ? }

? ? /**

? ? * 初始化webview

? ? */

? ? private void initWebView() {

? ? ? ? //首先設置Webview支持JS代碼

? ? ? ? webView.getSettings().setJavaScriptEnabled(true);

? ? ? ? //Webview自己處理超鏈接(Webview的監聽器非常多,封裝一個特殊的監聽類來處理)

? ? ? ? webView.setWebViewClient(new WebViewClient() {

? ? ? ? ? ? /**

? ? ? ? ? ? * 當打開超鏈接的時候,回調的方法

? ? ? ? ? ? * WebView:自己本身webView

? ? ? ? ? ? * url:即將打開的url

? ? ? ? ? ? */

? ? ? ? ? ? @Override

? ? ? ? ? ? public boolean shouldOverrideUrlLoading(WebView view, String url) {

? ? ? ? ? ? ? ? //自己處理新的url

? ? ? ? ? ? ? ? webView.loadUrl(url);

? ? ? ? ? ? ? ? //true就是自己處理

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? ? ? //重寫頁面打開和結束的監聽。打開時彈出菊花

? ? ? ? ? ? /**

? ? ? ? ? ? * 界面打開的回調

? ? ? ? ? ? */

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onPageStarted(WebView view, String url, Bitmap favicon) {

? ? ? ? ? ? ? ? if (progressDialog != null && progressDialog.isShowing()) {

? ? ? ? ? ? ? ? ? ? progressDialog.dismiss();

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? //彈出菊花

? ? ? ? ? ? ? ? progressDialog = new ProgressDialog(JSActivity.this);

? ? ? ? ? ? ? ? progressDialog.setTitle("提示");

? ? ? ? ? ? ? ? progressDialog.setMessage("軟軟正在拼命加載……");

? ? ? ? ? ? ? ? progressDialog.show();

? ? ? ? ? ? }

? ? ? ? ? ? /**

? ? ? ? ? ? * 重寫頁面打開和結束的監聽。打開時彈出菊花,關閉時隱藏菊花

? ? ? ? ? ? * 界面打開完畢的回調

? ? ? ? ? ? */

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onPageFinished(WebView view, String url) {

? ? ? ? ? ? ? ? //隱藏菊花:不為空,正在顯示。才隱藏

? ? ? ? ? ? ? ? if (progressDialog != null && progressDialog.isShowing()) {

? ? ? ? ? ? ? ? ? ? progressDialog.dismiss();

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? //設置進度條

? ? ? ? //WebChromeClient與webViewClient的區別

? ? ? ? //webViewClient處理偏界面的操作:打開新界面,界面打開,界面打開結束

? ? ? ? //WebChromeClient處理偏js的操作

? ? ? ? webView.setWebChromeClient(new WebChromeClient() {

? ? ? ? ? ? /**

? ? ? ? ? ? * 進度改變的回調

? ? ? ? ? ? * WebView:就是本身

? ? ? ? ? ? * newProgress:即將要顯示的進度

? ? ? ? ? ? */

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onProgressChanged(WebView view, int newProgress) {

? ? ? ? ? ? ? ? if (progressDialog != null && progressDialog.isShowing())

? ? ? ? ? ? ? ? ? ? progressDialog.setMessage("軟軟正在拼命加載……" + newProgress + "%");

? ? ? ? ? ? }

? ? ? ? ? ? /**

? ? ? ? ? ? * 重寫alert、confirm和prompt的彈出效果,并把用戶操作的結果回調給JS

? ? ? ? ? ? */

? ? ? ? ? ? /**

? ? ? ? ? ? * Webview加載html中有alert()執行的時候,會回調這個方法

? ? ? ? ? ? * url:當前Webview顯示的url

? ? ? ? ? ? * message:alert的參數值

? ? ? ? ? ? * JsResult:java將結果回傳到js中

? ? ? ? ? ? */

? ? ? ? ? ? @Override

? ? ? ? ? ? public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {

? ? ? ? ? ? ? ? AlertDialog.Builder builder = new AlertDialog.Builder(JSActivity.this);

? ? ? ? ? ? ? ? builder.setTitle("提示:看到這個,說明Java成功重寫了Js的Alert方法");

? ? ? ? ? ? ? ? builder.setMessage(message);//這個message就是alert傳遞過來的值

? ? ? ? ? ? ? ? builder.setPositiveButton("確定", new OnClickListener() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void onClick(DialogInterface dialog, int which) {

? ? ? ? ? ? ? ? ? ? ? ? //處理確定按鈕了,且通過jsresult傳遞,告訴js點擊的是確定按鈕

? ? ? ? ? ? ? ? ? ? ? ? result.confirm();

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? builder.setOnCancelListener(new DialogInterface.OnCancelListener() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void onCancel(DialogInterface dialog) {

? ? ? ? ? ? ? ? ? ? ? ? //防止用戶點擊對話框外圍,再次點擊按鈕頁面無響應

? ? ? ? ? ? ? ? ? ? ? ? result.cancel();

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? builder.show();

? ? ? ? ? ? ? ? //自己處理

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? ? ? /**

? ? ? ? ? ? * Webview加載html中有confirm執行的時候,會回調這個方法

? ? ? ? ? ? * url:當前Webview顯示的url

? ? ? ? ? ? * message:alert的參數值

? ? ? ? ? ? * JsResult:java將結果回傳到js中

? ? ? ? ? ? */

? ? ? ? ? ? @Override

? ? ? ? ? ? public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {

? ? ? ? ? ? ? ? AlertDialog.Builder builder = new AlertDialog.Builder(JSActivity.this);

? ? ? ? ? ? ? ? builder.setTitle("提示:" +

? ? ? ? ? ? ? ? ? ? ? ? "看到這個,說明Java成功重寫了Js的Confirm方法");

? ? ? ? ? ? ? ? builder.setMessage(message);//這個message就是alert傳遞過來的值

? ? ? ? ? ? ? ? builder.setPositiveButton("確定", new OnClickListener() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void onClick(DialogInterface dialog, int which) {

? ? ? ? ? ? ? ? ? ? ? ? //處理確定按鈕了,且通過jsresult傳遞,告訴js點擊的是確定按鈕

? ? ? ? ? ? ? ? ? ? ? ? result.confirm();

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? builder.setNegativeButton("取消", new OnClickListener() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void onClick(DialogInterface dialog, int which) {

? ? ? ? ? ? ? ? ? ? ? ? //處理取消按鈕,且通過jsresult傳遞,告訴js點擊的是取消按鈕

? ? ? ? ? ? ? ? ? ? ? ? result.cancel();

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? builder.setOnCancelListener(new DialogInterface.OnCancelListener() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void onCancel(DialogInterface dialog) {

? ? ? ? ? ? ? ? ? ? ? ? //防止用戶點擊對話框外圍,再次點擊按鈕頁面無反應

? ? ? ? ? ? ? ? ? ? ? ? result.cancel();

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? builder.show();

? ? ? ? ? ? ? ? //自己處理

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? ? ? /**

? ? ? ? ? ? * Webview加載html中有prompt()執行的時候,會回調這個方法

? ? ? ? ? ? * url:當前Webview顯示的url

? ? ? ? ? ? * message:alert的參數值

? ? ? ? ? ? *defaultValue就是prompt的第二個參數值,輸入框的默認值

? ? ? ? ? ? * JsPromptResult:java將結果重新回傳到js中

? ? ? ? ? ? */

? ? ? ? ? ? @Override

? ? ? ? ? ? public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? final JsPromptResult result) {

? ? ? ? ? ? ? ? AlertDialog.Builder builder = new AlertDialog.Builder(JSActivity.this);

? ? ? ? ? ? ? ? builder.setTitle("提示:看到這個,說明Java成功重寫了Js的Prompt方法");

? ? ? ? ? ? ? ? builder.setMessage(message);//這個message就是alert傳遞過來的值

? ? ? ? ? ? ? ? //添加一個EditText

? ? ? ? ? ? ? ? final EditText editText = new EditText(JSActivity.this);

? ? ? ? ? ? ? ? editText.setText(defaultValue);//這個就是prompt 輸入框的默認值

? ? ? ? ? ? ? ? //添加到對話框

? ? ? ? ? ? ? ? builder.setView(editText);

? ? ? ? ? ? ? ? builder.setPositiveButton("確定", new OnClickListener() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void onClick(DialogInterface dialog, int which) {

? ? ? ? ? ? ? ? ? ? ? ? //獲取edittext的新輸入的值

? ? ? ? ? ? ? ? ? ? ? ? String newValue = editText.getText().toString().trim();

? ? ? ? ? ? ? ? ? ? ? ? //處理確定按鈕了,且過jsresult傳遞,告訴js點擊的是確定按鈕(參數就是輸入框新輸入的值,我們需要回傳到js中)

? ? ? ? ? ? ? ? ? ? ? ? result.confirm(newValue);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? builder.setNegativeButton("取消", new OnClickListener() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void onClick(DialogInterface dialog, int which) {

? ? ? ? ? ? ? ? ? ? ? ? //處理取消按鈕,且過jsresult傳遞,告訴js點擊的是取消按鈕

? ? ? ? ? ? ? ? ? ? ? ? result.cancel();

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? builder.setOnCancelListener(new DialogInterface.OnCancelListener() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void onCancel(DialogInterface dialog) {

? ? ? ? ? ? ? ? ? ? ? ? //防止用戶點擊對話框外圍,再次點擊按鈕頁面無反應

? ? ? ? ? ? ? ? ? ? ? ? result.cancel();

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? builder.show();

? ? ? ? ? ? ? ? //自己處理

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? //java與js回調,自定義方法

? ? ? ? //1.java調用js

? ? ? ? //2.js調用java

? ? ? ? //首先java暴露接口,供js調用

? ? ? ? /**

? ? ? ? * obj:暴露的要調用的對象

? ? ? ? * interfaceName:對象的映射名稱 ,object的對象名,在js中可以直接調用

? ? ? ? * 在html的js中:JSTest.showToast(msg)

? ? ? ? * 可以直接訪問JSTest,這是因為JSTest掛載到js的window對象下了

? ? ? ? */

? ? ? ? webView.addJavascriptInterface(new Object() {

? ? ? ? ? ? //定義要調用的方法

? ? ? ? ? ? //msg由js調用的時候傳遞

? ? ? ? ? ? @JavascriptInterface

? ? ? ? ? ? public void showToast(String msg) {

? ? ? ? ? ? ? ? Toast.makeText(getApplicationContext(),

? ? ? ? ? ? ? ? ? ? ? ? msg, Toast.LENGTH_SHORT).show();

? ? ? ? ? ? }

? ? ? ? }, "JSTest");

? ? }

? ? @TargetApi(Build.VERSION_CODES.KITKAT)

? ? public void onSum(View view){

? ? ? ? webView.evaluateJavascript("sum(1,2)", new ValueCallback<String>() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onReceiveValue(String value) {

? ? ? ? ? ? ? ? Toast.makeText(getApplicationContext(),

? ? ? ? ? ? ? ? ? ? ? ? "相加結果:"+value, Toast.LENGTH_SHORT).show();

? ? ? ? ? ? }

? ? ? ? });

? ? }

? ? public void onDoing(View view){

? ? ? ? String msg = "測試";

? ? ? ? webView.loadUrl("javascript:showInfoFromJava('"+msg+"')");

? ? }

? ? @Override

? ? public void onBackPressed() {

? ? ? ? if (webView.canGoBack()) {

? ? ? ? ? ? //返回上一個頁

? ? ? ? ? ? webView.goBack();

? ? ? ? ? ? return ;

? ? ? ? }

? ? ? ? super.onBackPressed();

? ? }

}

布局文件activity_js.xml

<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"

? ? android:orientation="vertical"

? ? tools:context=".JSoupHtmlActivity">

? ? <Button

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:onClick="onSum"

? ? ? ? android:text="Java調用JS的Sum方法"

? ? ? ? tools:ignore="OnClick" />

? ? <Button

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:onClick="onDoing"

? ? ? ? android:text="Java調用JS的? showInfoFromJava 方法"

? ? ? ? tools:ignore="OnClick" />

? ? <WebView

? ? ? ? android:id="@+id/webView"

? ? ? ? android:layout_width="fill_parent"

? ? ? ? android:layout_height="fill_parent" />

</LinearLayout>

代碼過程描述的廢話我就不多說了,注釋寫的算是比較仔細了,另外再強調兩點需要注意的地方:

1、不要忘記通過setJavaScriptEnabled(true)設置webview支持JS代碼

2、在使用addJavascriptInterface方法添加掛載對象時,要注意在Android4.2之后需要給對象方法加上@JavascriptInterface注解。

3、重繪alert、confirm和prompt的彈出效果之后,在對話框結束之后一定要調用result.confirm()或者result.cancel()兩個方法中的一個,否則會出現后續再次點擊html頁面按鈕,頁面無響應的情況

---------------------

作者:流船

來源:CSDN

原文:https://blog.csdn.net/qq_35229022/article/details/79739048

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容