Why does Android OS 8 WebVew with HTML select tag crash the app

前端 未结 9 2607
傲寒
傲寒 2020-12-15 20:24

I\'ve got a hybrid Cordova Android app, and the app crashes when user tap on a drop-down box in my WebView running on Android OS 8. I\'ve created a simple page

9条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-15 21:14

    Actually found a workaround for this a little while ago that allowed us to continue subclassing Resources and not crash our WebViews. The caveat is we can't let our WebView see or interact with our resources subclass AND we must create the WebView programmaticaly. The first step is exposing method in the Resources subclass to pull the original resources back out.

    Lets say our resources subclass is called CustomResourcesWrapper and our ContextWrapper subclass is called CustomContextWrapper.

    First we update the CustomResourcesWrapper so we can access the original Resources object

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

    We're also assuming the CustomContextWrapper looks something like this...

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

    Then we create a static helper method to "unwrap" our custom resources and hide them

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

    When it comes time to create a WebView, do it ensure the Context we pass to it runs through the above method i.e. WebView webView = new WebView(unwrapCustomContext(context)). I'm not 100% sure why, but the ContextThemeWrapper is a required part of this hack.

提交回复
热议问题