android.os.ResultReceiver$MyResultReceiver.this$0
references org.chromium.content.browser.ContentViewCore$2$1.this$1(anonymous subcalss of android.os.ResultReceiver)
references org.chromium.content.browser.ContentViewCore$2.this$0
references org.chromium.content.browser.ContentViewCore.mContainerView
references android.webkit.WebView.mContext
leaks ***.WebActivity instance
android.view.accessibility.AccessibilityManager$1.this$0(anonymous sunclass of android.view.accessibility.IAccessibilityManagerClient$Stub)
references android.view.accessibility.AccessibilityManager.mAccesssibilityStateChangeListeners
references java.util.concurrent.CopyOnWriteArrayList.elements
references array java.lang.Object[].[1]
references org.chromium.content.browser.ContentViewCore.mContainerView
references android.webkit.WebView.mContext
leaks ***.WebActivity instance
WebView extends AbsoluteLayout 故拥有View的属性mContext属性,持有了Activity的对象
/**
* The application environment this view lives in.
* This field should be made private, so it is hidden from the SDK.
* {@hide}
*/
@ViewDebug.ExportedProperty(deepExport = true)
protected Context mContext;
在WebView实例化的过程中,具体参考 2017-09-13-WebView实例化的问题,有句代码调用
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());
}
}
过程中实例化了 com.android.webview.chromium.WebViewChromiumFactoryProvider 并调用了
@Override
public WebViewProvider createWebView(WebView webView, WebView.PrivateAccess privateAccess) {
return new WebViewChromium(this, webView, privateAccess, mShouldDisableThreadChecking);
}
然后实例化了 com.android.webview.chromium.WebViewChromium ,其中WebView的对象也传递到了这里
在WebViewChromium类中可以看到一个属性 mAwContents
// The WebView wrapper for ContentViewCore and required browser compontents.
AwContents mAwContents;
在这个方法中 mAwContents 完成了实例化赋值
private void initForReal() {
AwContentsStatics.setRecordFullDocument(sRecordWholeDocumentEnabledByApi
|| mAppTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP);
mAwContents = new AwContents(mFactory.getBrowserContextOnUiThread(), mWebView, mContext,
new InternalAccessAdapter(), new WebViewNativeDrawGLFunctorFactory(),
mContentsClientAdapter, mWebSettings.getAwSettings(),
new AwContents.DependencyFactory() {
@Override
public AutofillProvider createAutofillProvider(
Context context, ViewGroup containerView) {
return mFactory.createAutofillProvider(context, mWebView);
}
});
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();
}
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);
}
在init方法中调用了initForReal
// WebViewProvider methods --------------------------------------------------------------------
@Override
// BUG=6790250 |javaScriptInterfaces| was only ever used by the obsolete DumpRenderTree
// so is ignored. TODO: remove it from WebViewProvider.
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void init(final Map<String, Object> javaScriptInterfaces,
final boolean privateBrowsing) {
...
mFactory.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();
}
}
});
}
而init的调用者 就是WebView,在WebView的构造器中
/**
* @hide
*/
@SuppressWarnings("deprecation") // for super() call into deprecated base class constructor.
protected WebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes,
Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) {
super(context, attrs, defStyleAttr, defStyleRes);
...
ensureProviderCreated();
mProvider.init(javaScriptInterfaces, privateBrowsing);
...
}
这里的Provider实质上就是WebViewChromium的实例,其中上一句代码的ensureProviderCreated,就是去保证这个provider的存在。
为什么这里主要提到了 AwContents 呢?
org.chromium.content.browser.ContentViewCore
/**
* Provides a Java-side 'wrapper' around a WebContent (native) instance.
* Contains all the major functionality necessary to manage the lifecycle of a ContentView without
* being tied to the view system.
*/
@JNINamespace("content")
public class ContentViewCore
implements AccessibilityStateChangeListener, ScreenOrientationObserver
/**
* Sets a new container view for this {@link ContentViewCore}.
*
* <p>WARNING: This method can also be used to replace the existing container view,
* but you should only do it if you have a very good reason to. Replacing the
* container view has been designed to support fullscreen in the Webview so it
* might not be appropriate for other use cases.
*
* <p>This method only performs a small part of replacing the container view and
* embedders are responsible for:
* <ul>
* <li>Disconnecting the old container view from this ContentViewCore</li>
* <li>Updating the InternalAccessDelegate</li>
* <li>Reconciling the state of this ContentViewCore with the new container view</li>
* <li>Tearing down and recreating the native GL rendering where appropriate</li>
* <li>etc.</li>
* </ul>
*/
public void setContainerView(ViewGroup containerView) {
TraceEvent.begin();
if (mContainerView != null) {
mPastePopupMenu = null;
mInputConnection = null;
hidePopupsAndClearSelection();
}
mContainerView = containerView;
mPositionObserver = new ViewPositionObserver(mContainerView);
mContainerView.setWillNotDraw(false); // TODO(epenner): Remove (http://crbug.com/436689)
mContainerView.setClickable(true);
mViewAndroidDelegate.updateCurrentContainerView();
for (ContainerViewObserver observer : mContainerViewObservers) {
observer.onContainerViewChanged(mContainerView);
}
TraceEvent.end();
}
有泄漏日志可以看到是因为ContentViewCore持有的mContainerView泄漏了,而mContainerView是由于 AwContents 的调用来赋值的
why? please go on ...
在AwContents的构造器中调用了 setNewAwContents()
/* Common initialization routine for adopting a native AwContents instance into this
* java instance.
*
* TAKE CARE! This method can get called multiple times per java instance. Code accordingly.
* ^^^^^^^^^ See the native class declaration for more details on relative object lifetimes.
*/
private void setNewAwContents(long newAwContentsPtr) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
setNewAwContentsPreO(newAwContentsPtr);
} else {
// Move the TextClassifier to the new ContentViewCore.
TextClassifier textClassifier =
mContentViewCore == null ? null : mContentViewCore.getCustomTextClassifier();
setNewAwContentsPreO(newAwContentsPtr);
if (textClassifier != null) mContentViewCore.setTextClassifier(textClassifier);
}
}
其中的 setNewAwContentsPre0()
// Helper for setNewAwContents containing everything which applies to pre-O.
private void setNewAwContentsPreO(long newAwContentsPtr) {
...
mContentViewCore = new ContentViewCore(mContext, PRODUCT_VERSION);
mViewAndroidDelegate = new AwViewAndroidDelegate(
mContainerView, mContentsClient, mContentViewCore.getRenderCoordinates());
initializeContentViewCore(mContentViewCore, mContext, mViewAndroidDelegate,
mInternalAccessAdapter, webContents, new AwGestureStateListener(),
mWindowAndroid.getWindowAndroid());
nativeSetJavaPeers(mNativeAwContents, this, mWebContentsDelegate, mContentsClientBridge,
mIoThreadClient, mInterceptNavigationDelegate, mAutofillProvider);
mWebContents = mContentViewCore.getWebContents();
...
}
这里实例化了ContentViewCore,并调用了方法initializeContentViewCore(),其中调用了ContentViewCore的initialize()方法,为ContentViewCore的mContainerView属性赋了值。注意这里,传入的参数是ViewAndroidDelegate viewDelegate,而mViewAndroidDelegate是由前一步来实例化的。
mViewAndroidDelegate = new AwViewAndroidDelegate(mContainerView, mContentsClient, mContentViewCore.getRenderCoordinates());
而AwContents这里的 mContainerView 就是 WebView .
那么到了这里基本上就完成了,由WebView的Context到ContentViewCore的mContainerView的过程。