Android和H5吏垮、Js進行交互調(diào)用
Android開發(fā)過程中,我們或多或少都會用到webview卧土,使用webview來展示一些經(jīng)常變動的界面更加方便簡單惫皱,也已于維護。另一方面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 加載的話,那么當你點擊頁面中的鏈接的時候友酱,頁面將會在你手機默認的瀏覽器上打開晴音。那如果想要在頁面在App內(nèi)中打開的話,那么就得設置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頁面锤躁,防止點擊鏈接跳轉到系統(tǒng)瀏覽器
? ? ? ? ? ? ? ? ? ? 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() {
? ? ? //重寫頁面打開和結束的監(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();
? ? ? }
? ? ? /**
? ? ? * 界面打開完畢的回調(diào)
? ? ? */
? ? ? @Override
? ? ? public void onPageFinished(WebView view, String url) {
? ? ? ? ? //隱藏對話框:不為空,正在顯示澎迎。才隱藏關閉
? ? ? ? ? if (progressDialog != null && progressDialog.isShowing()) {
? ? ? ? ? ? ? progressDialog.dismiss();
? ? ? ? ? }
? ? ? }
? });
讓進度條顯示頁面加載進度:
//設置進度條
? ? ? ? //WebChromeClient與webViewClient的區(qū)別
? ? ? ? //webViewClient處理偏界面的操作:打開新界面庐杨,界面打開,界面打開結束
? ? ? ? //WebChromeClient處理偏js的操作
? ? ? ? webView.setWebChromeClient(new WebChromeClient() {
? ? ? ? ? ? /**
? ? ? ? ? ? * 進度改變的回調(diào)
? ? ? ? ? ? * WebView:就是本身
? ? ? ? ? ? * newProgress:即將要顯示的進度
? ? ? ? ? ? */
? ? ? ? ? ? @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的代碼灵份。
//首先設置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(),
? ? ? ? ? ? ? ? ? ? ? ? "相加結果:"+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成功調(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)用的對象名稱袁铐,對應下面代碼中的JSText
對應的JS代碼
function jsJava(){
? ? ? ? //調(diào)用java的方法,頂級對象横浑,java方法
? ? ? ? //可以直接訪問JSTest剔桨,這是因為JSTest掛載到js的window對象下了
? ? ? ? JSTest.showToast("我是被JS執(zhí)行的Android代碼");
? ? }
對應的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掛載到js的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的彈出效果,并把用戶具體操作結果回調(diào)給JS
alert彈窗:
重繪confirm彈窗:
重繪prompt彈窗:
具體代碼:
/**
? ? ? ? ? ? * Webview加載html中有alert()執(zhí)行的時候隐轩,會回調(diào)這個方法
? ? ? ? ? ? * url:當前Webview顯示的url
? ? ? ? ? ? * message:alert的參數(shù)值
? ? ? ? ? ? * 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執(zhí)行的時候瘫俊,會回調(diào)這個方法
? ? ? ? ? ? * url:當前Webview顯示的url
? ? ? ? ? ? * message:alert的參數(shù)值
? ? ? ? ? ? * 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()執(zhí)行的時候川尖,會回調(diào)這個方法
? ? ? ? ? ? * url:當前Webview顯示的url
? ? ? ? ? ? * message:alert的參數(shù)值
? ? ? ? ? ? *defaultValue就是prompt的第二個參數(shù)值,輸入框的默認值
? ? ? ? ? ? * 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點擊的是確定按鈕(參數(shù)就是輸入框新輸入的值,我們需要回傳到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篓冲,這里為了方便學習,
我已經(jīng)寫了一個html文件放置在了Asset文件中宠哄,通過 file:///android_asset/test.html 來進行加載壹将。
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="用戶點擊了確認按鈕";
? ? ? }else{
? ? ? ? document.getElementById("p").innerHTML="用戶點擊了取消按鈕";
? ? ? }
? ? }
? ? function jsPrompt(){
? ? ? ? //第一個參數(shù)是提示
? ? ? ? //第二個參數(shù)是默認值
? ? ? ? var r = prompt("請輸入姓名:","小明同學");
? ? ? ? if (r != null)
? ? ? ? {
? ? ? ? document.getElementById("p").innerHTML="用戶輸入的姓名為:"+r;
? ? ? ? }else{
? ? ? ? document.getElementById("p").innerHTML="用戶點擊了取消按鈕";
? ? ? ? }
? ? }
? ? function jsJava(){
? ? ? ? //調(diào)用java的方法,頂級對象承粤,java方法
? ? ? ? //可以直接訪問JSTest暴区,這是因為JSTest掛載到js的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() {
? ? ? ? //首先設置Webview支持JS代碼
? ? ? ? webView.getSettings().setJavaScriptEnabled(true);
? ? ? ? //Webview自己處理超鏈接(Webview的監(jiān)聽器非常多,封裝一個特殊的監(jiān)聽類來處理)
? ? ? ? webView.setWebViewClient(new WebViewClient() {
? ? ? ? ? ? /**
? ? ? ? ? ? * 當打開超鏈接的時候辛臊,回調(diào)的方法
? ? ? ? ? ? * WebView:自己本身webView
? ? ? ? ? ? * url:即將打開的url
? ? ? ? ? ? */
? ? ? ? ? ? @Override
? ? ? ? ? ? public boolean shouldOverrideUrlLoading(WebView view, String url) {
? ? ? ? ? ? ? ? //自己處理新的url
? ? ? ? ? ? ? ? webView.loadUrl(url);
? ? ? ? ? ? ? ? //true就是自己處理
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? ? ? //重寫頁面打開和結束的監(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ān)聽觉鼻。打開時彈出菊花徐绑,關閉時隱藏菊花
? ? ? ? ? ? * 界面打開完畢的回調(diào)
? ? ? ? ? ? */
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onPageFinished(WebView view, String url) {
? ? ? ? ? ? ? ? //隱藏菊花:不為空诫咱,正在顯示。才隱藏
? ? ? ? ? ? ? ? if (progressDialog != null && progressDialog.isShowing()) {
? ? ? ? ? ? ? ? ? ? progressDialog.dismiss();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? //設置進度條
? ? ? ? //WebChromeClient與webViewClient的區(qū)別
? ? ? ? //webViewClient處理偏界面的操作:打開新界面刃唤,界面打開隔心,界面打開結束
? ? ? ? //WebChromeClient處理偏js的操作
? ? ? ? webView.setWebChromeClient(new WebChromeClient() {
? ? ? ? ? ? /**
? ? ? ? ? ? * 進度改變的回調(diào)
? ? ? ? ? ? * WebView:就是本身
? ? ? ? ? ? * newProgress:即將要顯示的進度
? ? ? ? ? ? */
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onProgressChanged(WebView view, int newProgress) {
? ? ? ? ? ? ? ? if (progressDialog != null && progressDialog.isShowing())
? ? ? ? ? ? ? ? ? ? progressDialog.setMessage("軟軟正在拼命加載……" + newProgress + "%");
? ? ? ? ? ? }
? ? ? ? ? ? /**
? ? ? ? ? ? * 重寫alert、confirm和prompt的彈出效果尚胞,并把用戶操作的結果回調(diào)給JS
? ? ? ? ? ? */
? ? ? ? ? ? /**
? ? ? ? ? ? * Webview加載html中有alert()執(zhí)行的時候硬霍,會回調(diào)這個方法
? ? ? ? ? ? * url:當前Webview顯示的url
? ? ? ? ? ? * message:alert的參數(shù)值
? ? ? ? ? ? * 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執(zhí)行的時候侍咱,會回調(diào)這個方法
? ? ? ? ? ? * url:當前Webview顯示的url
? ? ? ? ? ? * message:alert的參數(shù)值
? ? ? ? ? ? * 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()執(zhí)行的時候偎箫,會回調(diào)這個方法
? ? ? ? ? ? * url:當前Webview顯示的url
? ? ? ? ? ? * message:alert的參數(shù)值
? ? ? ? ? ? *defaultValue就是prompt的第二個參數(shù)值,輸入框的默認值
? ? ? ? ? ? * 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點擊的是確定按鈕(參數(shù)就是輸入框新輸入的值恶复,我們需要回傳到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回調(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掛載到js的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(),
? ? ? ? ? ? ? ? ? ? ? ? "相加結果:"+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>
代碼過程描述的廢話我就不多說了,注釋寫的算是比較仔細了套么,另外再強調(diào)兩點需要注意的地方:
1培己、不要忘記通過setJavaScriptEnabled(true)設置webview支持JS代碼
2、在使用addJavascriptInterface方法添加掛載對象時违诗,要注意在Android4.2之后需要給對象方法加上@JavascriptInterface注解漱凝。
3疮蹦、重繪alert诸迟、confirm和prompt的彈出效果之后,在對話框結束之后一定要調(diào)用result.confirm()或者result.cancel()兩個方法中的一個愕乎,否則會出現(xiàn)后續(xù)再次點擊html頁面按鈕阵苇,頁面無響應的情況
---------------------
作者:流船
來源:CSDN
原文:https://blog.csdn.net/qq_35229022/article/details/79739048