所以,我们实际上遇到了同样的问题(使用WebView
在保留的Fragment
以防止页面重新加载,同时不泄漏Activity
上下文),简短的回答似乎是没有真正干净的方法来做到这一点。我什至尝试过定制WebView
返回主机的子类Activity
的窗口令牌而不是WebView
自己的令牌,没有成功。
正如您所建议的,我们最终使用反射来修改底层上下文:
public static boolean setContext(View v, Context ctx) {
try {
final Field contextField = View.class.getDeclaredField("mContext");
contextField.setAccessible(true);
contextField.set(v, ctx);
return (v.getContext() == ctx);
} catch (IllegalAccessException | NoSuchFieldException e) {
Log.e(TAG, String.valueOf(e), e);
return false;
}
}
这只是设置mContext
场上的View
实例,如果修改成功则返回 true。然而,我最近看到了另一个建议(并且我没有测试过这个,所以 YMMV) 使用MutableContextWrapper
。所以你会膨胀WebView
与Activity
Context
,包裹在MutableContextWrapper
。然后,当您需要释放先前的引用时,您可以将其强制转换WebView
's Context
to a MutableContextWrapper
,然后设置底座Context
到新的Activity
。所以像这样来膨胀布局:
MutableContextWrapper contextWrapper = new MutableContextWrapper(activity);
WebView webView = (WebView) LayoutInflater.from(contextWrapper)
.inflate(R.layout.your_webview_layout, theParent, false);
然后,重新连接到新的Activity
:
if (webView.getContext() instanceof MutableContextWrapper) {
((MutableContextWrapper) webView.getContext()).setBaseContext(newActivity);
}