1. 程式人生 > >android 與js互動

android 與js互動

年後請了幾天假,今天第一天上班,這邊部落格本來應該年前寫的,唉。。太懶了
先扯點沒用的,總結下17年吧。
外包公司,專案倒是很多很雜,但總覺得論起細節、深度不夠,但也學習到了很多的東西,而且慶幸的是和三個android同事一起進步、成長,成了很好的朋友。空閒時間寫了一個安卓專案“AsYouLike”和一個小程式“我很隨便的”,雖然不是特別難,但是自己一直以來的一個想法,總算實現了,還是有點驕傲的哈哈。自從我買了ipad之後,下班回去做好飯,就會開啟虎牙看一起看欄目的士兵突擊,一遍一遍,看不夠似的,很多不經意的話,再重新聽的時候,會有別樣的感覺。想起幾句,分享一下:我怕失落,怕丟失了始終怕不在乎。有容乃大,無欲則剛,容是別人,欲是自己。什麼都要成功,搞不好就要失敗。最初看的時候,裡面會覺得裡面的一句話“不拋棄,不放棄”,說的只是戰友情,後來才明白,也是對自己追求理想的不拋棄不放棄。許三多跟成才說,人不能太舒服了,太舒服了會出問題,對於我們尤其適用。袁朗淘汰成才的時候,問成才,你的努力是為了什麼,為了一個結果虛耗人生?虛耗人生?那怎樣才算不虛耗人生呢?袁朗去部隊看到獨守營房的許三多時評價他不焦慮,這個時代應該很多人都會很焦慮吧,如此焦慮,如此功利。年底換到新的公司,是一家做自己產品的,今天剛剛知道,另一位同事要離職,我來這家公司其實是因為面試的時候覺得他比較牛才來的,但現在又不會太失落,總要承擔一定的壓力,總要靠自己啊,這不是什麼壞事。
展望一下吧,18年希望自己能花更多的時間去學習,更有耐心,多跑步多鍛鍊身體,把兩個專案優化一下,開發藝術探索看完,android提升的同時學習一下js和c。好了,先扯到這吧。

參考自:

說到Android與js互動,避免不了的就是WebView。
想要開啟網頁時不使用預設的瀏覽器開啟,而是使用當前的WebView,做如下設定即可:

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new WebViewClient());

如果當你點選連結的時候你想做更多的控制,則需要重寫shouldOverrideUrlLoading方法。shouldOverrideUrlLoading返回true表示你已經處理此次請求。返回false表示有webview自行處理,一般都是把此url加載出來。post請求並不會回撥這個函式。
比如有一個下面的需求:有一個web頁面上一個連結,點選後我們不希望webview直接轉到連結的頁面,而是起一個我們自己寫的activity,此時就需要讓shouldOverrideUrlLoading返回true,如下:

private WebViewClient webViewClient = new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (match(url)) {
                foo1();
                return  true;
            }
            return false;
        }
    };

常用的工具類:
**1.WebSettings類:**對WebView進行配置和管理
較常用的設定:

WebSettings webSettings = webView.getSettings();

//設定自適應螢幕,兩者合用
webSettings.setUseWideViewPort(true); //將圖片調整到適合webview的大小
webSettings.setLoadWithOverviewMode(true); // 縮放至螢幕的大小

//去掉縮放按鈕
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
	webSettings.setBuiltInZoomControls(true);
	webSettings.setDisplayZoomControls(false);
} else {
	try {
            Class webview = Class.forName("android.webkit.WebView");
            Method method = webview.getMethod("getZoomButtonsController");
            ZoomButtonsController zoom_controll = (ZoomButtonsController) method.invoke(this, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
}

//設定快取模式
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
//快取模式如下:
//LOAD_CACHE_ONLY: 不使用網路,只讀取本地快取資料
//LOAD_DEFAULT: (預設)根據cache-control決定是否從網路上取資料。
//LOAD_NO_CACHE: 不使用快取,只從網路獲取資料.
//LOAD_CACHE_ELSE_NETWORK,只要本地有,無論是否過期,或者no-cache,都使用快取中的資料。

webSettings.setLoadsImagesAutomatically(true);//支援自動載入圖片
webSettings.setDefaultTextEncodingName("utf-8");//設定編碼格式


**2.WebViewClient:**處理各種通知(開始載入/載入結束/載入失敗等) & 請求事件
onPageStarted 開始載入 (顯示載入進度條等)
onPageFinished 載入結束 (隱藏載入進度條等)
onReceivedError 載入失敗(可在此處載入錯誤提示頁面)
shouldOverrideUrlLoading (對要開啟的連結做判斷進而有不同的操作)
onReceivedSslError 任何HTTPS請求,遇到SSL錯誤時都會回撥這個方法(在處理ssl錯誤時,遇到不信任的證書可以進行特殊處理,例如對域名進行判斷,針對自己公司的域名“放行”,防止進入醜陋的錯誤證書頁面。也可以與Chrome一樣,彈出ssl證書疑問彈窗,給使用者選擇的餘地。)
eg考拉做法:

@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
    if (UrlUtils.isKaolaHost(getUrl())) {
        handler.proceed();
    } else {
        super.onReceivedSslError(view, handler, error);
    }
}

**3.WebChromeClient:**輔助 WebView 處理 Javascript 的對話方塊,載入進度,網站圖示/標題等
onProgressChanged 載入進度
onReceivedTitle 網站標題
onJsAlert 當開啟js彈窗時回撥 返回true則消費掉此js彈窗,返回false則開啟預設的提示框
onJsConfirm 當開啟js確認框時回撥
onJsPrompt 當開啟js輸入框時回撥

android呼叫js程式碼

要呼叫的js程式碼如下:

<html>
<head>
    <meta charset="utf-8">
    <title>SilenceBurst</title>
    <script>
            function callJs(){
                alert("Android呼叫了js的callJs方法");
            }
    </script>
</head>
</html>
		final WebView webView = findViewById(R.id.web_view);
        WebSettings settings = webView.getSettings();
        //允許與js互動
        settings.setJavaScriptEnabled(true);
        //允許js彈窗
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        webView.loadUrl("file:///android_asset/call_js.html");

		//通過設定WebChromeClient來處理js的alert函式
        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
                AlertDialog alertDialog = new AlertDialog.Builder(CallJsActivity.this)
                        .setTitle("呼叫Js")
                        .setMessage(message)
                        .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                result.confirm();
                            }
                        })
                        .create();
                alertDialog.setCanceledOnTouchOutside(false);
                alertDialog.show();
                return true;
            }
        });

1.loadUrl

//呼叫javascript的callJs方法
webView.loadUrl("javascript:callJs()");

2.evaluateJavascript

webView.evaluateJavascript("javascript:callJs()", new ValueCallback<String>() {
                    @Override
                    public void onReceiveValue(String value) {
                        //value為js返回的結果
                        Toast.makeText(CallJsActivity.this, value, Toast.LENGTH_LONG).show();
                    }
                });

總結: 使用WebView的evaluateJavascript方法呼叫js程式碼比loadUrl效率更高,易於獲取返回值,更簡潔(該方法執行不會使頁面重新整理,而loadUrl會),但evaluateJavascript方法Android4.4之後才可以使用
建議:

		// Android版本變數
        final int version = Build.VERSION.SDK_INT;
		// 因為該方法在 Android 4.4 版本才可使用,所以使用時需進行版本判斷
        if (version < 18) {
            mWebView.loadUrl("javascript:callJS()");
        } else {
            mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
                @Override
                public void onReceiveValue(String value) {
                    //此處為 js 返回的結果
                }
            });
        }

js呼叫android程式碼

1.addJavascriptInterface
定義一個與JS物件對映關係的Android類:AndroidtoJs
多次呼叫addJavascriptInterface之後的會把之前的覆蓋

//繼承自Object
public class AndroidToJs extends Object {
    //被js呼叫的方法必須加入@JavascriptInterface註解
    @JavascriptInterface
    public void hello(String msg) {
        System.out.println(msg);
    }
}

呼叫

	//設定與js互動的許可權
	settings.setJavaScriptEnabled(true);
	//將java物件對映到js物件
	webView.addJavascriptInterface(new AndroidToJs(), "test");
	webView.loadUrl("file:///android_asset/add_javascript_interface.html");

add_javascript_interface

<html>
<head>
    <meta charset="utf-8">
    <title>SilenceBurst</title>
    <script>
            function callAndroid(){
                test.hello("js呼叫了Android的hello方法");
            }
    </script>
</head>
<body>
<button type="button" onclick="callAndroid()">點我調android方法</button>
</body>
</html>

2.通過shouldOverrideUrlLoading回撥攔截url

//設定與js互動的許可權
settings.setJavaScriptEnabled(true);
//允許js彈窗
settings.setJavaScriptCanOpenWindowsAutomatically(true);
webView.setWebViewClient(new WebViewClient() {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        Uri uri = Uri.parse(url);
        /*
         *根據協議的引數判斷是否是需要的url
         * 一般通過scheme(協議格式)和authority(協議名)判斷
         */
        if ("js".equals(uri.getScheme()) && "webview".equals(uri.getAuthority())) {
        //到此處根據即可做相關的操作,即js呼叫android完成,下面程式碼傳返回值給js
            Set<String> parameters = uri.getQueryParameterNames();
            Iterator<String> iterator = parameters.iterator();
            HashMap<String, String> map = new HashMap<>();
            while (iterator.hasNext()) {
                String next = iterator.next();
                map.put(next, uri.getQueryParameter(next));
            }
            //hello方法做一個吐司提示js呼叫android成功
            String result = hello(map);
            //傳遞返回值給js 單引號要注意啊!!!
            webView.loadUrl("javascript:getResult('" + result + "')");
            return true;
        }
        return super.shouldOverrideUrlLoading(view, url);
    }
});
//通過設定WebChromeClient來處理js的alert函式
webView.setWebChromeClient(new WebChromeClient() {
    @Override
    public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
        AlertDialog alertDialog = new AlertDialog.Builder(mContext)
                .setTitle("呼叫Js")
                .setMessage(message)
                .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        result.confirm();
                    }
                })
                .create();
        alertDialog.setCanceledOnTouchOutside(false);
        alertDialog.show();
        return true;
    }
});
webView.loadUrl("file:///android_asset/should_override_url_loading.html");

should_override_url_loading

<html>
<head>
    <meta charset="utf-8">
    <title>SilenceBurst</title>
    <script>
            function callAndroid(){
                 /*約定的url協議為:js://webview?arg1=111&arg2=222*/
                 document.location = "js://webview?arg1=111&arg2=222";
            }

            function getResult(result){
                alert("result is"+result);
            }
    </script>
</head>
<body>
<button type="button" onclick="callAndroid()">點我調android方法</button>
</body>
</html>

3.通過 WebChromeClient 的onJsAlert、onJsConfirm、onJsPrompt方法回撥攔截JS對話方塊alert、confirm、prompt 訊息
(類似shouldOverrideUrlLoading攔截)

//設定與js互動的許可權
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
webView.setWebChromeClient(new WebChromeClient() {
    @Override
    public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
        Uri uri = Uri.parse(message);
        if ("js".equals(uri.getScheme()) && "webview".equals(uri.getAuthority())) {
            //此處即為js呼叫android時,android程式碼裡判斷攔截掉js彈出的輸入框,並傳入值到js提示框
            //引數:代表訊息框的返回值(輸入值)
            result.confirm("js 呼叫android的方法成功了");
            return true;
        }
        return super.onJsPrompt(view, url, message, defaultValue, result);
    }
});
webView.loadUrl("file:///android_asset/on_js_prompt.html");

on_js_prompt

<html>
<head>
    <meta charset="utf-8">
    <title>SilenceBurst</title>
    <script>
            function clickPrompt(){
                var result = prompt("js://webview?arg1=111&arg2=222");
                alert("webview"+result);
            }
    </script>
</head>
<body>
<button type="button" onclick="clickPrompt()">點我調android方法</button>
</body>
</html>

相關推薦

安卓混淆之後,androidjs互動異常原因

解決方案:需要js互動程式碼不被混淆掉,加入以下程式碼即可 -keepclassmembers class com.taohaohuo365.taohaohuo.activity.H5Activity$AndroidAndJSInterface { public *; } -keepcla

AndroidJS互動

Android與JS的方法互調 在Android的開發過程中、遇到一個新需求、那就是讓Java程式碼和Javascript程式碼進行互動、在IOS中實現起來很麻煩、而在Android中相對來說容易多了、Android對這種互動進行了很好的封裝、我們可以很簡單的用

Androidjs互動,帶進度條的載入H5頁面

private void initWebView() { WebSettings settings = wvResumeDetail.getSettings(); //支援JavaScript指令碼語言 settings

AndroidJS互動篇--JSBridge的使用

在android日常開發中,大家或多或少都會碰到原生巢狀web頁面,大家可以使用傳統的方式實現Native與JS的互動,這裡就不多介紹了,現在我們簡單介紹下網上目前比較流行的已經封裝好的框架JsBridge。可參考官網github地址:點選開啟連結先看下接下來將要實現的效果圖

android js互動

年後請了幾天假,今天第一天上班,這邊部落格本來應該年前寫的,唉。。太懶了 先扯點沒用的,總結下17年吧。 外包公司,專案倒是很多很雜,但總覺得論起細節、深度不夠,但也學習到了很多的東西,而且慶幸的是和三個android同事一起進步、成長,成了很好的朋友。空閒時間

簡化AndroidJS互動,JsBridge框架全面解析

今日科技快訊近日,滴滴順風車披露了一組數字,預測春運前後,跨城出行以7天為一個週期,呈“潮汐式”

Androidjs互動(四)自定義cordova外掛

首先昨天我做測試的時候js端一直無法呼叫寫在js的方法後來查了資料才知道是在index.html中使用js時 需要刪除這一行 <meta http-equiv="Content-Security-Policy" content="default-src 'self'

WebView---Androidjs互動例項

Android 中可以通過webview來實現和js的互動,在程式中呼叫js程式碼,只需要將webview控制元件的支援js的屬性設定為true Android(Java)與JavaScript(HTML)互動有四種情況: 1) Android(Java)呼叫HTML中j

AndroidJS互動監聽,url實時變化的方法.

private class MyWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view,

androidjs互動的方式(包括三種)

關於android月js或者說html互動的方式,在很早的版本中是通過android端新增js支援,然後傳遞一個js操作本地方法的物件,然後就可以呼叫本地的方法。在後邊的版本為了統一管理,添加了@JavascriptInterface  ,只有添加了這個標誌的方法才能被js

Android開發之Webview中原生JS互動

文章目錄 概述 使用場景 互動方式 Java呼叫JS程式碼 JS呼叫Java程式碼 總結 概述 由於手機硬體資源的快速提升,使得采用混合開發的可能性逐漸成為現實並且流行起來。Android開發中

Android之webViewjs互動

一、java呼叫js操作: 1.佈局檔案: <WebView android:id="@+id/web" android:layout_width="match_parent" android:layout_height="mat

解決Android簽名混淆後WebViewJS互動失效的問題

最近做了個網頁端微信支付的小功能,測試版還好好的,混淆打包後,寫的方法webview無法呼叫,意識到混淆除了問題,於是在網上找了一些大神的解決方案,再根據自己的實際解決過程,列出來一個完整的解決方法。 Android4.2以上版本呼叫js介面需要在方法使用宣告@JavascriptInterfa

Android筆記之 WebviewJs互動-詳情舉例

Android呼叫網頁自身Js 你好! 這是你第一次使用 Markdown編輯器 所展示的歡迎頁。如果你想學習如何使用Markdown編輯器, 可以仔細閱讀這篇文章,瞭解一下Markdown的基本語法知識。 本地(asset)網頁androidcalljs.h

Android中Webviewjs互動

1.js呼叫Android程式碼Android端:webView.addJavascriptInterface(new WebHost(this),"js");向WebView註冊一個名叫“js”的物件,然後在JS中可以訪問js這個物件,呼叫這個物件裡的一些方法。 publi

Android WebViewJS互動及訊息處理

一、WebView與JS互動 1.JS呼叫本地方法 這個功能的實現還是比較容易的。直接呼叫WebView的該方法就可以新增介面了,不過先要啟動互動 ? 1 2 3 4 // 啟用javascript  mWebView.getSettin

Android webViewjs 互動以及jsbridge框架原始碼分析

1.簡單篇 如何實現簡單的android 呼叫js 與js呼叫android 讓webview做一下操作 private void init(Context context){ WebSettings setting =

WebView的使用以及AndroidJs互動

1.WebView基礎使用 1.想要使用WebView,需要在<manifest>中新增許可權: <uses-permission android:name="android.permission.INTERNET" />2.我們可以在xml

Android Webview優化及Js互動

在做的一個專案裡主要是webview載入HTML頁面,移動端工作量不多,主要是webview的優化問題,雖說看似很簡單,但仍遇到了幾個令人頭疼的問題。 問題解決及優化之路主要經歷了以下幾個過程: 1、第一次開啟webview耗時過長 剛開始在做webvie

Android webviewjs互動上傳圖片

最近專案中用到webview,並且有上傳圖片功能,iOS不用做任何處理,但Android就不行了,調不到相簿,後百度才知道這是Android webview的侷限性,需要自己擴充套件WebChromeClient來實現,話不多說直接上程式碼: 第一步:擴充套件WebChro