android webview 二次驗證流程分析 shouldOverrideUrlLoading深度分析

轉自:https://blog.csdn.net/a0407240134/article/details/51482021

一. shouldOverrideUrlLoading的含義 

Sdk中的解釋

public boolean shouldOverrideUrlLoading (WebView view, String url)Added in API level 1. 

Give the host application a chance to take over the control when a new url is about to be loaded in the current WebView. If WebViewClient is not provided, by default WebView will ask Activity Manager to choose the proper handler for the url. If WebViewClient is provided, return true means the host application handles the url, while return false means the current WebView handles the url. This method is not called for requests using the POST "method".

 

這裏面一共蘊含着三層意思:

1.若沒有設置 WebViewClient 則由系統(Activity Manager )處理該 url,通常是使用瀏覽器打開或彈出瀏覽器選擇對話框。

2.若設置 WebViewClient 且該方法返回 true ,則說明由應用的代碼處理該 url,WebView 不處理。

3.若設置 WebViewClient 且該方法返回 false,則說明由 WebView 處理該 url,即用 WebView 加載該 url

 

shouldOverrideUrlLoading調用時機是:

第一:瀏覽器內核內部檢測到需要load另一個url,此時就有可能通過調用shouldOverrideUrlLoading來請求host app怎麼做。(原因參考後面的"源碼分析")。

第二:host app通過webview.loadUrl來load的頁面,都不會觸發shouldOverrideUrlLoading(原因參考後面的"源碼分析")

二.二次驗證期間shouldOverrideUrlLoading和onPageFinished調用分析

 

 

只分析到加載完登陸界面,後面的流程和這類似。我們可以看到,shouldOverrideUrlLoading返回true比返回false多調用了一次onPageFinished. 這次onPageFinished是在load fail觸發的.在瀏覽器內核裏會區分load complete和load fail, 但是在app層,就只有onPageFinished.

 

下面是Setting中shouldOverrideUrlLoading源碼

@Override

public boolean shouldOverrideUrlLoading(WebView view, String url) {

mRedirectCount++;

mRedirectUrl = url;

view.loadUrl(url);

return true;

}

在shouldOverrideUrlLoading中直接使用webview.loadUrl(url),然後return true. 效果和直接return false是一樣的,且onPageFinished會少一次調用.

在shouldOverrideUrlLoading中調用webview.loadUrl(url),也沒啥意義.因爲直接return false後,webview會自動去load該url.

所以修改方法是:去掉view.loadUrl(url)並返回false.

 

 

源碼分析:

在AwContents.java中給出了什麼時候才調用shouldOverrideUrlLoading (chromium46中)

源碼如下:

final boolean isLoadUrl = (transitionType & PageTransition.FROM_API) != 0;

...

if ((!isLoadUrl || isRedirect) && !isBackForward && !isReload

                    && !navigationParams.isPost) {

if (!mContentsClient.hasWebViewClient()) {

ignoreNavigation = AwContentsClient.sendBrowsingIntent(mContext, url,

navigationParams.hasUserGesture

                    || navigationParams.hasUserGestureCarryover,

                    navigationParams.isRedirect);

} else {

ignoreNavigation = mContentsClient.shouldOverrideUrlLoading(url);

}

}

 

從上面可以看出,瀏覽器如下行爲:前進後退(isBackForward ),刷新(isReload),Post請求(navigationParams.isPost)都不會觸發shouldOverrideUrlLoading.

 

如果都不是以上行爲,還要滿足isRedirect或!isLoadUrl 才能觸發shouldOverrideUrlLoading.

isRedirect就是重定向的url,即重定向url也會觸發shouldOverrideUrlLoading;這裏重點介紹以下isLoadUrl.

凡是webview.loadUrl出load頁面的,isLoadUrl都是true(原因是webview.loadUrl最終會調到loadUrl(LoadUrlParams params),進而params.setTransitionType(params.getTransitionType() | PageTransition.FROM_API)).

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章