Android和js、H5進(jìn)行交互數(shù)據(jù)

Android和H5、Js進(jìn)行交互調(diào)用

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

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

1 Webview加載頁面

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

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

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

例如:加載網(wǎng)頁

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

如果只是這樣調(diào)用webview.loadUrl 加載的話,那么當(dāng)你點擊頁面中的鏈接的時候,頁面將會在你手機(jī)默認(rèn)的瀏覽器上打開。那如果想要在頁面在App內(nèi)中打開的話,那么就得設(shè)置setWebViewClient:

mWebView.setWebViewClient(new WebViewClient() {

? ? ? ? @Override

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

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

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

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

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

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

? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? //這里我們自己重新加載新的url頁面,防止點擊鏈接跳轉(zhuǎn)到系統(tǒng)瀏覽器

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

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

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? });

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

@Override

? ? public void onBackPressed() {

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

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

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

? ? ? ? ? ? return ;

? ? ? ? }

? ? ? ? super.onBackPressed();

? ? }

二、給webview添加加載新頁面的進(jìn)度條。

開啟和關(guān)閉進(jìn)度條

webView.setWebViewClient(new WebViewClient() {

? ? ? //重寫頁面打開和結(jié)束的監(jiān)聽。打開時彈出對話框,關(guān)閉時隱藏

? ? ? /**

? ? ? * 界面打開的回調(diào)

? ? ? */

? ? ? @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();

? ? ? }

? ? ? /**

? ? ? * 界面打開完畢的回調(diào)

? ? ? */

? ? ? @Override

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

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

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

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

? ? ? ? ? }

? ? ? }

? });

讓進(jìn)度條顯示頁面加載進(jìn)度:

//設(shè)置進(jìn)度條

? ? ? ? //WebChromeClient與webViewClient的區(qū)別

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

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

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

? ? ? ? ? ? /**

? ? ? ? ? ? * 進(jìn)度改變的回調(diào)

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

? ? ? ? ? ? * newProgress:即將要顯示的進(jìn)度

? ? ? ? ? ? */

? ? ? ? ? ? @Override

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

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

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

? ? ? ? ? ? }

三、android本地通過java調(diào)用HTML頁面中的javaScript方法

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

//首先設(shè)置Webview支持JS代碼

webView.getSettings().setJavaScriptEnabled(true);

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

若有返回值時我們可以調(diào)用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(),

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

? ? ? ? ? ? }

? ? ? ? });

? ? }

? ? public void onDoing(View view){

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

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

? ? }

對應(yīng)的js方法

? ? function sum(a,b){

? ? ????return a+b;

? ? }

? ? function showInfoFromJava(){

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

? ? }

四、js調(diào)用Android本地java方法

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

public void addJavascriptInterface(Object object, String name);

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

2 name參數(shù):這里的name就是我們可以在JS里面調(diào)用的對象名稱,對應(yīng)下面代碼中的JSText

對應(yīng)的JS代碼

function jsJava(){

? ? ? ? //調(diào)用java的方法,頂級對象,java方法

? ? ? ? //可以直接訪問JSTest,這是因為JSTest掛載到j(luò)s的window對象下了

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

? ? }

對應(yīng)的Java代碼:

//java與js回調(diào),自定義方法

? ? ? ? //1.java調(diào)用js

? ? ? ? //2.js調(diào)用java

? ? ? ? //首先java暴露接口,供js調(diào)用

? ? ? ? /**

? ? ? ? * obj:暴露的要調(diào)用的對象

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

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

? ? ? ? * 可以直接訪問JSTest,這是因為JSTest掛載到j(luò)s的window對象下了

? ? ? ? */

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

? ? ? ? ? ? //定義要調(diào)用的方法

? ? ? ? ? ? //msg由js調(diào)用的時候傳遞

? ? ? ? ? ? @JavascriptInterface

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

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

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

? ? ? ? ? ? }

? ? ? ? }, "JSTest");

五、重繪alert 、confirm和prompt的彈出效果,并把用戶具體操作結(jié)果回調(diào)給JS

alert彈窗:

重繪confirm彈窗:

重繪prompt彈窗:

具體代碼:

/**

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

? ? ? ? ? ? * url:當(dāng)前Webview顯示的url

? ? ? ? ? ? * message:alert的參數(shù)值

? ? ? ? ? ? * JsResult:java將結(jié)果回傳到j(luò)s中

? ? ? ? ? ? */

? ? ? ? ? ? @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執(zhí)行的時候,會回調(diào)這個方法

? ? ? ? ? ? * url:當(dāng)前Webview顯示的url

? ? ? ? ? ? * message:alert的參數(shù)值

? ? ? ? ? ? * JsResult:java將結(jié)果回傳到j(luò)s中

? ? ? ? ? ? */

? ? ? ? ? ? @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()執(zhí)行的時候,會回調(diào)這個方法

? ? ? ? ? ? * url:當(dāng)前Webview顯示的url

? ? ? ? ? ? * message:alert的參數(shù)值

? ? ? ? ? ? *defaultValue就是prompt的第二個參數(shù)值,輸入框的默認(rèn)值

? ? ? ? ? ? * JsPromptResult:java將結(jié)果重新回傳到j(luò)s中

? ? ? ? ? ? */

? ? ? ? ? ? @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 輸入框的默認(rèn)值

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

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

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

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

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

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

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

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

? ? ? ? ? ? ? ? ? ? ? ? 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,這里為了方便學(xué)習(xí),

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

webview成功加載頁面后,會出現(xiàn)四個新的按鈕,點擊不同的按鈕,會產(chǎn)生不同的效果

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

<html>

<head>

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

? ? <title>Document</title>

? ? <script>

? ? function jsAlert(){

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

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

? ? }

? ? function jsConFirm(){

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

? ? ? if (r == true)

? ? ? {

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

? ? ? }else{

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

? ? ? }

? ? }

? ? function jsPrompt(){

? ? ? ? //第一個參數(shù)是提示

? ? ? ? //第二個參數(shù)是默認(rèn)值

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

? ? ? ? if (r != null)

? ? ? ? {

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

? ? ? ? }else{

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

? ? ? ? }

? ? }

? ? function jsJava(){

? ? ? ? //調(diào)用java的方法,頂級對象,java方法

? ? ? ? //可以直接訪問JSTest,這是因為JSTest掛載到j(luò)s的window對象下了

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

? ? }

? ? function sum(a,b){

? ? return a+b;

? ? }

? ? function showInfoFromJava(){

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

? ? }

? ? </script>

</head>

<body>

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

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

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

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

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

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

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

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

<input type="button" value="調(diào)用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() {

? ? ? ? //首先設(shè)置Webview支持JS代碼

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

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

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

? ? ? ? ? ? /**

? ? ? ? ? ? * 當(dāng)打開超鏈接的時候,回調(diào)的方法

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

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

? ? ? ? ? ? */

? ? ? ? ? ? @Override

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

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

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

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

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? ? ? //重寫頁面打開和結(jié)束的監(jiān)聽。打開時彈出菊花

? ? ? ? ? ? /**

? ? ? ? ? ? * 界面打開的回調(diào)

? ? ? ? ? ? */

? ? ? ? ? ? @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();

? ? ? ? ? ? }

? ? ? ? ? ? /**

? ? ? ? ? ? * 重寫頁面打開和結(jié)束的監(jiān)聽。打開時彈出菊花,關(guān)閉時隱藏菊花

? ? ? ? ? ? * 界面打開完畢的回調(diào)

? ? ? ? ? ? */

? ? ? ? ? ? @Override

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

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

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

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

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? //設(shè)置進(jìn)度條

? ? ? ? //WebChromeClient與webViewClient的區(qū)別

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

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

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

? ? ? ? ? ? /**

? ? ? ? ? ? * 進(jìn)度改變的回調(diào)

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

? ? ? ? ? ? * newProgress:即將要顯示的進(jìn)度

? ? ? ? ? ? */

? ? ? ? ? ? @Override

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

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

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

? ? ? ? ? ? }

? ? ? ? ? ? /**

? ? ? ? ? ? * 重寫alert、confirm和prompt的彈出效果,并把用戶操作的結(jié)果回調(diào)給JS

? ? ? ? ? ? */

? ? ? ? ? ? /**

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

? ? ? ? ? ? * url:當(dāng)前Webview顯示的url

? ? ? ? ? ? * message:alert的參數(shù)值

? ? ? ? ? ? * JsResult:java將結(jié)果回傳到j(luò)s中

? ? ? ? ? ? */

? ? ? ? ? ? @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) {

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

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

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

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

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

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? ? ? /**

? ? ? ? ? ? * Webview加載html中有confirm執(zhí)行的時候,會回調(diào)這個方法

? ? ? ? ? ? * url:當(dāng)前Webview顯示的url

? ? ? ? ? ? * message:alert的參數(shù)值

? ? ? ? ? ? * JsResult:java將結(jié)果回傳到j(luò)s中

? ? ? ? ? ? */

? ? ? ? ? ? @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) {

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

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

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

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

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

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? ? ? /**

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

? ? ? ? ? ? * url:當(dāng)前Webview顯示的url

? ? ? ? ? ? * message:alert的參數(shù)值

? ? ? ? ? ? *defaultValue就是prompt的第二個參數(shù)值,輸入框的默認(rèn)值

? ? ? ? ? ? * JsPromptResult:java將結(jié)果重新回傳到j(luò)s中

? ? ? ? ? ? */

? ? ? ? ? ? @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 輸入框的默認(rèn)值

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

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

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

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

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

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

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

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

? ? ? ? ? ? ? ? ? ? ? ? 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) {

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

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

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

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

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

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? //java與js回調(diào),自定義方法

? ? ? ? //1.java調(diào)用js

? ? ? ? //2.js調(diào)用java

? ? ? ? //首先java暴露接口,供js調(diào)用

? ? ? ? /**

? ? ? ? * obj:暴露的要調(diào)用的對象

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

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

? ? ? ? * 可以直接訪問JSTest,這是因為JSTest掛載到j(luò)s的window對象下了

? ? ? ? */

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

? ? ? ? ? ? //定義要調(diào)用的方法

? ? ? ? ? ? //msg由js調(diào)用的時候傳遞

? ? ? ? ? ? @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(),

? ? ? ? ? ? ? ? ? ? ? ? "相加結(jié)果:"+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調(diào)用JS的Sum方法"

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

? ? <Button

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:onClick="onDoing"

? ? ? ? android:text="Java調(diào)用JS的? showInfoFromJava 方法"

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

? ? <WebView

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

? ? ? ? android:layout_width="fill_parent"

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

</LinearLayout>

代碼過程描述的廢話我就不多說了,注釋寫的算是比較仔細(xì)了,另外再強(qiáng)調(diào)兩點需要注意的地方:

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

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

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

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

作者:流船

來源:CSDN

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容