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 //未完待续

上一篇 下一篇

猜你喜欢

热点阅读