我有一个混合的Cordova Android应用程序,当用户点击我在Android OS 8上运行的WebView
的下拉框时,应用程序崩溃。我创建了一个带有{{{ 1}}标签,问题是可重现的。我有一个解决方法是做我自己的弹出警报选择,但只是想知道这是否发生在其他任何人以及这是否是一个OS8 <select>
错误。
以下是包含WebView
标记
https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_select
以下是我的崩溃日志
<select>
我的问题与此
不一样Trying to open SELECT tag in Android WebView crashes the application
2018年1月9日更新: 我还没有解决方案,我的临时解决方法是删除标签并只使用输入。当用户选择此元素时,我们将事件传递给本机代码以弹出一个用于选择的对话框,并在用户进行选择后更新输入。
2018年3月23日更新: 经过一番调查后,我发现如果WebView在片段中,它只会崩溃,但不会在活动中崩溃。
我在下面的帖子中找到了评论:
Trying to open SELECT tag in Android WebView crashes the application
“单击SELECT标记时,Android会在内部使用本机AlertDialog显示其选项。 必须使用Activity上下文创建Webview,因为AlertDialog实例需要一个Activity上下文。“
我认为这是Android中的一个错误,可能无法正确处理Fragment的上下文。
2018年4月17日更新:
正如肯尼指出的那样,从https://issuetracker.google.com/issues/77246450开始,谷歌说
您不能继承资源对象的子类 - 这从未得到支持,并且只能偶然发生(这就是为什么它现在被标记为已弃用)。框架需要了解所有资源对象,以便在加载webview时更新它们(因为webview会向资产管理器添加其他路径)。
编辑2018年11月29日 似乎这个问题困扰了很多人。
答案 0 :(得分:3)
我在Android 8.0上遇到同样的问题。 最后我解决了。 尝试将compileSdkVersion更新为26, 并将您的com.android.support:appcompat-v7更新为26。
答案 1 :(得分:2)
看起来像这个bug: https://issuetracker.google.com/issues/77246450
不要将资源分类......显然不会被修复。
答案 2 :(得分:2)
如果仍然有人遇到此问题,我发现不是我的代码在子类化Resources类,而是我在使用的Google支持库版本。更新了支持库版本,它的工作原理很吸引人!
答案 3 :(得分:0)
我深入了解崩溃日志。虽然这个答案无法解决您的问题,但您可能会获得一些有用的见解
我不确定为什么它会在Android 8.0上发生,但我无法在Android 8.0模拟器上重现这一点
答案 4 :(得分:0)
经过一番调查,我已经将问题分离到OS8内的Fragment中的WebView。我的解决方法是为该特定流使用Activity而不是Fragment。在我看来片段中的Android缺陷。
答案 5 :(得分:0)
也许您在ContextWrapper
课程中使用自定义Activity
。就我而言,我重写了attachBaseContext
方法。检查此方法并使用super.attachBaseContext(newBase)
。
答案 6 :(得分:0)
实际上,不久前找到了一种解决方法,它使我们可以继续对Resources
进行子类化,而不会使WebView崩溃。需要注意的是,我们不能让WebView看到资源子类或与资源子类进行交互,而我们必须以编程方式创建WebView。第一步是在Resources子类中公开方法,以撤回原始资源。
可以说我们的资源子类称为CustomResourcesWrapper
,而我们的ContextWrapper
子类称为CustomContextWrapper
。
首先,我们更新CustomResourcesWrapper
,以便可以访问原始的Resources
对象
public class CustomResourcesWrapper {
public static Resources findOriginalResources(Context context) {
if (context.getResources() instanceof CustomResourcesWrapper) {
return ((CustomResourcesWrapper) context.getResources()).getOriginalResources();
}
if (context instanceof ContextWrapper) {
return findOriginalResources(((ContextWrapper) context).getBaseContext());
}
return context.getResources();
}
private Resources getOriginalResources() {
return originalResources;
}
}
我们还假设CustomContextWrapper
看起来像这样...
public class CustomContextWrapper extends ContextWrapper {
private final Resources wrappedResources;
public CustomContextWrapper(Context base, Resources resources) {
super(base);
this.wrappedResources = resources;
}
@Override
public Resources getResources() {
return wrappedResources;
}
}
然后,我们创建一个静态助手方法来“解包”我们的自定义资源并隐藏它们
// the method name is a bit of a misnomer,
// we're actually unwrapping, then re-wrapping
public static Context unwrapCustomContext(Context wrapped) {
Resources originalResources = CustomResourcesWrapper.findOriginalResources(wrapped);
Context customUnwrappedContext = new CustomContextWrapper(wrapped, originalResources);
return new ContextThemeWrapper(customUnwrappedContext, android.support.v7.appcompat.R.style.Theme_AppCompat_Light);
}
当需要创建WebView时,请确保我们传递给它的Context
通过上述方法运行,即WebView webView = new WebView(unwrapCustomContext(context))
。我不是100%知道为什么,但是ContextThemeWrapper
是此hack的必需部分。
答案 7 :(得分:0)
在AndroidX平台上(限于最低compileSDKVersion 28),我还在带有弹出微调器的棉花糖模拟器上遇到了此问题。我没有在Resources附近走走,所以这仍然是其中一个支持库的平台问题。
我设法使其正常运行-不是通过将Webview移至Activity(尽管我确实尝试过,但这不是必需的),而是通过以包装的上下文和标准AppCompat主题以编程方式添加了它:
val webView = WebView(ContextThemeWrapper(activity, R.style.Theme_AppCompat_Light))
binding.webViewContainer.addView(webView)
我不知道wtf会在这里发生,但现在可以正常工作。祝你好运!
编辑 我对此进行了更多研究,发现了导致我麻烦的依赖性。材料组件库的特定版本实际上是在webviews中进行归纳的(确切地说是1.1.0-alpha06)。 I have asked a question on it here,以及一个示例项目。
答案 8 :(得分:-1)
看起来你正在为Textview设置Integer值。尝试使用String.valueOf(value)
在Textview中设置值。