java class 只有声明没有定义

java class only declaration no definition

Java 的新手并调试未正确更新的 WebView android 应用程序。要了解 WebView 的 onDraw() 中发生了什么,请在此处查看源代码 http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.2.2_r1/android/webkit/WebView.java?av=f

显示 onDraw() class 调用

 mProvider.init(javaScriptInterfaces, privateBrowsing);

mProvider.init(...) 在这里 http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.2.2_r1/android/webkit/WebViewProvider.java#WebViewProvider.init%28java.util.Map%2Cboolean%29

但只有声明没有定义。在 C++ 中,定义在 cpp 文件中。 java 中是否有任何等价物?.

mProvider.init(javaScriptInterfaces, privateBrowsing);

WebViewClassic

实现

相关的grepcode link是here.

如果 link 不可用,这里是原始方法:

@Override
public void init(Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) {
    Context context = mContext;

    // Used by the chrome stack to find application paths
    JniUtil.setContext(context);

    mCallbackProxy = new CallbackProxy(context, this);
    mViewManager = new ViewManager(this);
    L10nUtils.setApplicationContext(context.getApplicationContext());
    mWebViewCore = new WebViewCore(context, this, mCallbackProxy, javaScriptInterfaces);
    mDatabase = WebViewDatabaseClassic.getInstance(context);
    mScroller = new OverScroller(context, null, 0, 0, false); //TODO Use OverScroller's flywheel
    mZoomManager = new ZoomManager(this, mCallbackProxy);

    /* The init method must follow the creation of certain member variables,
     * such as the mZoomManager.
     */
    init();
    setupPackageListener(context);
    setupProxyListener(context);
    setupTrustStorageListener(context);
    updateMultiTouchSupport(context);

    if (privateBrowsing) {
        startPrivateBrowsing();
    }

    mAutoFillData = new WebViewCore.AutoFillData();
    mEditTextScroller = new Scroller(context);
}

编辑:

既然你对 mProviderinit() 更感兴趣,那么让我们来看看 mProvider 的路径。

首先我们看到它定义在WebView中class.

private WebViewProvider mProvider;

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());
    }
}

从上面的代码块我们可以看到ensureProviderCreater()方法初始化了mProvider变量。此方法在 WebView class.

的非弃用构造函数中调用

首先调用 getFactory() 方法,让我们看一下:

private static synchronized WebViewFactoryProvider getFactory() {
    // For now the main purpose of this function (and the factory abstration) is to keep
    // us honest and minimize usage of WebViewClassic internals when binding the proxy.
    checkThread();
    return WebViewFactory.getProvider();
}

让我们保留 checkThread() 并转而查看 WebViewFactory.getProvider();

static WebViewFactoryProvider getProvider() {
    synchronized (sProviderLock) {
        // For now the main purpose of this function (and the factory abstraction) is to keep
        // us honest and minimize usage of WebViewClassic internals when binding the proxy.
        if (sProviderInstance != null) return sProviderInstance;

        // For debug builds, we allow a system property to specify that we should use the
        // Chromium powered WebView. This enables us to switch between implementations
        // at runtime. For user (release) builds, don't allow this.
        if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean("webview.use_chromium", false)) {
            StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
            try {
                sProviderInstance = loadChromiumProvider();
                if (DEBUG) Log.v(LOGTAG, "Loaded Chromium provider: " + sProviderInstance);
            } finally {
                StrictMode.setThreadPolicy(oldPolicy);
            }
        }

        if (sProviderInstance == null) {
            if (DEBUG) Log.v(LOGTAG, "Falling back to default provider: "
                    + DEFAULT_WEBVIEW_FACTORY);
            sProviderInstance = getFactoryByName(DEFAULT_WEBVIEW_FACTORY,
                    WebViewFactory.class.getClassLoader());
            if (sProviderInstance == null) {
                if (DEBUG) Log.v(LOGTAG, "Falling back to explicit linkage");
                sProviderInstance = new WebViewClassic.Factory();
            }
        }
        return sProviderInstance;
    }
}

这里发生的事情可能不是很明显,但这就是它的要点。

它检查构建是否启用了调试,是否有系统变量 "webview.use_chromium" 以及是否设置为 "true"。

如果上述所有情况都发生,则加载 chromium webview 提供程序(原因在上面的评论中提到)。

如果不满足条件(例如,构建不在开发模式),我们要求 class 加载程序按实际解析为 android.webkit.WebViewClassic$Factory 的名称加载 DEFAULT_WEBVIEW_FACTORY(你能现在开始看到这一切融合在一起了吗?:))

所以最后除非我们满足某些特定条件 WebViewFactory.getProvider() 将 return WebViewClassic class 的内部 Factory class =] - WebViewClassic.Factory.

所以让我们回到最初的 ensureProviderCreated() 看看我们现在的立场。

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());
    }
}

OK,所以我们现在知道getFactory()会returnWebViewClassic.Factory,所以现在我们只需要检查那个工厂的createWebView方法。

@Override
public WebViewProvider createWebView(WebView webView, WebView.PrivateAccess privateAccess) {
    return new WebViewClassic(webView, privateAccess);
}

你可以清楚地看到它非常简单,它 return 是 WebViewClassic 的一个新实例,将 WebView 对象传递给它,因为我们从 WebView 调用它this 以及 privateAccess 参数也将是我们传递的 new PrivateAccess()

为了完整起见,这里是为 WebViewClassic:

调用的构造函数
public WebViewClassic(WebView webView, WebView.PrivateAccess privateAccess) {
    mWebView = webView;
    mWebViewPrivate = privateAccess;
    mContext = webView.getContext();
}

希望这能消除您对 mProvider 到底是什么以及它是如何制作的困惑。 :)