Android WebView笔记
2019-08-12 本文已影响0人
R7_Perfect
Android 25版本的webview源码:
@Widget
public class WebView extends AbsoluteLayout
implements ViewTreeObserver.OnGlobalFocusChangeListener,
ViewGroup.OnHierarchyChangeListener, ViewDebug.HierarchyHandler {
...
protected WebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes,
Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) {
super(context, attrs, defStyleAttr, defStyleRes);
if (context == null) {
throw new IllegalArgumentException("Invalid context argument");
}
sEnforceThreadChecking = context.getApplicationInfo().targetSdkVersion >=
Build.VERSION_CODES.JELLY_BEAN_MR2;
//检查是否在主线程
checkThread();
//WebViewFactoryProvider创建一个provider
ensureProviderCreated();
mProvider.init(javaScriptInterfaces, privateBrowsing);
// Post condition of creating a webview is the CookieSyncManager.getInstance() is allowed.
CookieSyncManager.setGetInstanceIsAllowed();
}
...
public void loadUrl(String url) {
checkThread();
mProvider.loadUrl(url);
}
}
可以看到都是由provider去处理的
provider初始化的地方:
private void ensureProviderCreated() {
checkThread();
if (mProvider == null) {
// As this can get called during the base class constructor chain, pass the minimum
// number of dependencies here; the rest are deferred to init().
mProvider = getFactory().createWebView(this, new PrivateAccess());
}
}
private static synchronized WebViewFactoryProvider getFactory() {
return WebViewFactory.getProvider();
}
getProvider:
static WebViewFactoryProvider getProvider() {
synchronized (sProviderLock) {
...
try {
Class<WebViewFactoryProvider> providerClass = getProviderClass();
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "providerClass.newInstance()");
try {
sProviderInstance = providerClass.getConstructor(WebViewDelegate.class)
.newInstance(new WebViewDelegate());
if (DEBUG) Log.v(LOGTAG, "Loaded provider: " + sProviderInstance);
return sProviderInstance;
} catch (Exception e) {
Log.e(LOGTAG, "error instantiating provider", e);
throw new AndroidRuntimeException(e);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
StrictMode.setThreadPolicy(oldPolicy);
}
}
}
private static Class<WebViewFactoryProvider> getProviderClass() {
...
try {
...
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getChromiumProviderClass()");
try {
...
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "Class.forName()");
try {
return (Class<WebViewFactoryProvider>) Class.forName(CHROMIUM_WEBVIEW_FACTORY,
true, clazzLoader);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
}
} catch (ClassNotFoundException e) {
...
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
}
} catch (MissingWebViewPackageException e) {
...
}
}
最终的位置:
private static final String CHROMIUM_WEBVIEW_FACTORY =
"com.android.webview.chromium.WebViewChromiumFactoryProvider"
看下WebViewChromiumFactoryProviderde的createWebView方法
createWebView(WebView webView, PrivateAccess privateAccess) {
WebViewChromium wvc = new WebViewChromium(this, webView, privateAccess);
synchronized (mLock) {
if (mWebViewsToStart != null) {
mWebViewsToStart.add(new WeakReference<WebViewChromium>(wvc));
}
}
return wvc;
}
WebViewChromium类:
class WebViewChromium implements WebViewProvider,
WebViewProvider.ScrollDelegate, WebViewProvider.ViewDelegate, SmartClipProvider {
public void init(final Map<String, Object> javaScriptInterfaces,
final boolean privateBrowsing) {
...
mRunQueue.addTask(new Runnable() {
@Override
public void run() {
initForReal();
if (privateBrowsing) {
// Intentionally irreversibly disable the webview instance, so that private
// user data cannot leak through misuse of a non-privateBrowing WebView
// instance. Can't just null out mAwContents as we never null-check it
// before use.
destroy();
}
}
});
}
private void initForReal() {
Context ctx = resourcesContextWrapper(mWebView.getContext());
mAwContents = new AwContents(mFactory.getBrowserContext(), mWebView, ctx,
new InternalAccessAdapter(), new WebViewNativeGLDelegate(),
mContentsClientAdapter, mWebSettings.getAwSettings());
if (mAppTargetSdkVersion >= Build.VERSION_CODES.KITKAT) {
// On KK and above, favicons are automatically downloaded as the method
// old apps use to enable that behavior is deprecated.
AwContents.setShouldDownloadFavicons();
}
AwContentsStatics.setRecordFullDocument(sRecordWholeDocumentEnabledByApi ||
mAppTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP);
if (mAppTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP) {
// Prior to Lollipop, JavaScript objects injected via addJavascriptInterface
// were not inspectable.
mAwContents.disableJavascriptInterfacesInspection();
}
// TODO: This assumes AwContents ignores second Paint param.
mAwContents.setLayerType(mWebView.getLayerType(), null);
}
}
可以看到Task实际都是由AwContents类完成的
至于AwContents //未完待续