Android WebView的几个核心类(framework源码): WebView 视图 WebViewClient WebView的回调类 WebViewProvider WebView的接口类 WebViewCore WebView核心类,持有 CallbackProxy 实例,通过mCallbackProxy回调到CallbackProxy WebCoreThread Web线程类 EventHub BrowserFrame -- Handler CallbackProxy -- Handler
WebBackForwardList
web主框架加载栈(后退/前进列表),内部维护一个ArrayList<WebHistoryItem>
持有CallbackProxy,当列表增加、减少或当前索引改变时,进行回调
WebBackForwardList.setClearPending() 将后退/前进列表标记为具有挂起清除
WebView.loadUrl() 代码
public void loadUrl(String url) {
checkThread();
loadUrlImpl(url);
}
private void loadUrlImpl(String url) {
if (url == null) {
return;
}
loadUrlImpl(url, null);
}
public void loadUrl(String url, Map<String, String> additionalHttpHeaders) {
checkThread();
loadUrlImpl(url, additionalHttpHeaders);
}
private void loadUrlImpl(String url, Map<String, String> extraHeaders) {
switchOutDrawHistory();
WebViewCore.GetUrlData arg = new WebViewCore.GetUrlData();
arg.mUrl = url;
arg.mExtraHeaders = extraHeaders;
mWebViewCore.sendMessage(EventHub.LOAD_URL, arg);
clearHelpers();
}
WebViewCore中Handler的handleMessage:
@Override
public void handleMessage(Message msg) {
...
case LOAD_URL: {
CookieManager.getInstance().waitForCookieOperationsToComplete();
GetUrlData param = (GetUrlData) msg.obj;
loadUrl(param.mUrl, param.mExtraHeaders);
break;
}
...
}
private void loadUrl(String url, Map<String, String> extraHeaders) {
if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, " CORE loadUrl " + url);
mBrowserFrame.loadUrl(url, extraHeaders);
}
}
BrowserFrame中的loadUrl
/**
* Load a url from the network or the filesystem into the main frame.
* Following the same behaviour as Safari, javascript: URLs are not passed
* to the main frame, instead they are evaluated immediately.
* @param url The url to load.
* @param extraHeaders The extra headers sent with this url. This should not
* include the common headers like "user-agent". If it does, it
* will be replaced by the intrinsic value of the WebView.
*/
public void loadUrl(String url, Map<String, String> extraHeaders) {
mLoadInitFromJava = true;
if (URLUtil.isJavaScriptUrl(url)) {
// strip off the scheme and evaluate the string
stringByEvaluatingJavaScriptFromString(
url.substring("javascript:".length()));
} else {
nativeLoadUrl(url, extraHeaders);
}
mLoadInitFromJava = false;
}
loadUrl中直接调用native层代码,
如果是js,走stringByEvaluatingJavaScriptFromString()
否则走:nativeLoadUrl()