由于webView存在安全漏洞,谷歌从5.1开始全面禁止系统应用使用webview,使用会导致应用崩溃错误提示:Caused by: java.lang.UnsupportedOperationException: For security reasons, WebView is not allowed in privileged processes 异常信息可以看出 是在 WebViewFactory.java 的getProvider 方法 抛出的。源码路径为 frameworks/base/core/java/android/webkit/WebViewFactory.java

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 WebView internals when binding the proxy.
            if (sProviderInstance != null) return sProviderInstance; //如果sProviderInstance不为空直接返回
             
          //1,判断,如果是系统id ,则抛出异常。
            final int uid = android.os.Process.myUid();
            if (uid == android.os.Process.ROOT_UID || uid == android.os.Process.SYSTEM_UID) {
                throw new UnsupportedOperationException(
                        "For security reasons, WebView is not allowed in privileged processes");
            }
 
            StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
            Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getProvider()");
            try {
                //2
                Class<WebViewFactoryProvider> providerClass = getProviderClass();
 
                Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "providerClass.newInstance()");
                try {
                    //3 给 sProviderInstance 赋值
                    sProviderInstance = providerClass.getConstructor(WebViewDelegate.class)
                            .newInstance(new WebViewDelegate());
                    if (DEBUG) Log.v(LOGTAG, "Loaded provider: " + sProviderInstance);
                    return sProviderInstance;
                } catch (Exception e) {
                    Log.e(LOGTAG, "error instantiating provider", e);
                    throw new AndroidRuntimeException(e);
                } finally {
                    Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
                }
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
                StrictMode.setThreadPolicy(oldPolicy);
            }
        }
    }

  如果是系统id,就抛出异常! 可以通过反射在调用webview 之前,给sProviderInstance 赋值,这样就可以了 在Application调用方法,兼容8.0

public static void hookWebView(){
    int sdkInt = Build.VERSION.SDK_INT;
    try {
      Class<?> factoryClass = Class.forName("android.webkit.WebViewFactory");
      Field field = factoryClass.getDeclaredField("sProviderInstance");
      field.setAccessible(true);
      Object sProviderInstance = field.get(null);
      if (sProviderInstance != null) {
        Log.i(TAG,"sProviderInstance isn't null");
        return;
      }
 
      Method getProviderClassMethod;
      if (sdkInt > 22) {
        getProviderClassMethod = factoryClass.getDeclaredMethod("getProviderClass");
      } else if (sdkInt == 22) {
        getProviderClassMethod = factoryClass.getDeclaredMethod("getFactoryClass");
      } else {
        Log.i(TAG,"Don't need to Hook WebView");
        return;
      }
      getProviderClassMethod.setAccessible(true);
      Class<?> factoryProviderClass = (Class<?>) getProviderClassMethod.invoke(factoryClass);
      Class<?> delegateClass = Class.forName("android.webkit.WebViewDelegate");
      Constructor<?> delegateConstructor = delegateClass.getDeclaredConstructor();
      delegateConstructor.setAccessible(true);
      if(sdkInt < 26){//低于Android O版本
        Constructor<?> providerConstructor = factoryProviderClass.getConstructor(delegateClass);
        if (providerConstructor != null) {
          providerConstructor.setAccessible(true);
          sProviderInstance = providerConstructor.newInstance(delegateConstructor.newInstance());
        }
      } else {
        Field chromiumMethodName = factoryClass.getDeclaredField("CHROMIUM_WEBVIEW_FACTORY_METHOD");
        chromiumMethodName.setAccessible(true);
        String chromiumMethodNameStr = (String)chromiumMethodName.get(null);
        if (chromiumMethodNameStr == null) {
          chromiumMethodNameStr = "create";
        }
        Method staticFactory = factoryProviderClass.getMethod(chromiumMethodNameStr, delegateClass);
        if (staticFactory!=null){
          sProviderInstance = staticFactory.invoke(null, delegateConstructor.newInstance());
        }
      }
 
      if (sProviderInstance != null){
        field.set("sProviderInstance", sProviderInstance);
        Log.i(TAG,"Hook success!");
      } else {
        Log.i(TAG,"Hook failed!");
      }
    } catch (Throwable e) {
      Log.w(TAG,e);
    }
  }

  

解决Android8.0系统应用打开webView报错的更多相关文章

  1. 解决windows64位系统上安装mysql-python报错

    解决windows64位系统上安装mysql-python报错 2018年03月12日 13:08:24 一个CD包 阅读数:1231    版权声明:本文为博主原创文章,未经博主允许不得转载. ht ...

  2. 一招解决OpenERP8.0安装旧版模块报错

    有喜欢尝鲜的网友开始玩8.0了,可是版本还没发布,社区的很多特别好的模块还没有升级到8,所以经常碰到模块无法安装的问题. No module name osv 网友提出将模块的 from osv im ...

  3. dotfuscator 在混淆.Net Framework 4.0以上版本的时候报错的解决方法

    dotfuscator 在混淆.Net Framework 4.0以上版本的时候报错的解决方法 在混淆的时候报错了,错误描述大致如下: Could not find a compatible vers ...

  4. 使用自编译的Emacs26.0.50build10版本,helm报错(已解决)

    使用自编译的Emacs26.0.50build10版本,helm报错(已解决) */--> code {color: #FF0000} pre.src {background-color: #0 ...

  5. 如何解决vue2.0 打包之后 打开index.html出现空白页

    如何解决vue2.0 打包之后 打开index.html出现空白页 1.打包之前修改三个文件       1.1.第一步,找到build文件,在webpack.prod.conf.js 第25行左右 ...

  6. Linux系统下启动MySQL报错:Neither host &#39;localhost.localdomain&#39; nor &#39;localhost&#39; could be looked up with

    Linux系统下启动MySQL报错:Neither host 'localhost.localdomain' nor 'localhost' could be looked up with 摘要 Li ...

  7. 打开eclipse报错:发现了以元素 'd:skin' 开头的无效内容。此处不应含有子元素。

    [错误] 打开eclipse报错:发现了以元素 ‘d:skin’ 开头的无效内容.此处不应含有子元素. [具体报错信息] Error parsing D:\Android-sdks\system-im ...

  8. 【WPF】弹窗定位、弹窗关闭后再打开的报错

    需求:点击按钮,打开一个弹窗. // 获得窗体实例 Window window = openDesignViewModel.View as Window; // 这是使用了WAF框架 //Window ...

  9. 开着idea,死机了,关机重启。重启之后,重新打开idea报错java.lang.AssertionError:upexpected content storage modification

    开着idea,死机了,关机重启.重启之后,重新打开idea报错java.lang.AssertionError:upexpected content storage modification. goo ...

随机推荐

  1. Maven手动导本地jar到项目

    第一步:先把目标jar安装在本地,下面是安装到本地的步骤:在cmd命令中,输入:mvn install:install-file -Dfile=C:\Users\Ter\Desktop\jqd_doc ...

  2. 有关dfs、bfs解决迷宫问题的个人见解

    可以使用BFS或者DFS方法解决的迷宫问题! 题目如下: kotori在一个n*m迷宫里,迷宫的最外层被岩浆淹没,无法涉足,迷宫内有k个出口.kotori只能上下左右四个方向移动.她想知道有多少出口是 ...

  3. JDK8从永生代到元数据区

    永生代 永生代默认的最大内存大小是在32位JVM上为64MB, 在64位JVM上为82MB.可以通过-XX:PermSize=[size]和-XX:MaxPermSize=[size]来调整. 永生代 ...

  4. Intellij IDEA debug断点调试技巧与总结详解篇

    1. Rerun . 这个就是结束debug模式,直接以run的方式重新跑某个程序.2. 直接跑完. 到下一个断点停下. 没有就直接跑完程序.3. 停止项目或者程序.要是自己的main呢. 点一下就停 ...

  5. 解决 niceScroll 自适应DOM 高度变化

    利用dataTable展示数据列表时,当选择每页显示数量时,滚动条还是按照页面初始化时显示的,导致无法滚动查看下面的数据,  在stackoverflower 找到一个可用的方法,但不知道为什么仅写  ...

  6. Python爬虫:现学现用xpath爬取豆瓣音乐

    爬虫的抓取方式有好几种,正则表达式,Lxml(xpath)与BeautifulSoup,我在网上查了一下资料,了解到三者之间的使用难度与性能 三种爬虫方式的对比. 这样一比较我我选择了Lxml(xpa ...

  7. Haffman编码

    Huffman树又称为最优树,是一种带权路径最短的树. 一.带权路径 在一棵树中我们把一个节点到另一个节点之间的通路叫做路径,在路径中每经过一个节点路径的长度就加一.如果对一个节点附上权值,则该节点的 ...

  8. python--osi七层模型

    OSI七层模型 OSI七层参考模型 学计算机的人想必都对OSI七层参考模型不陌生,OSI七层参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系.它是一个七层的.抽象的模型 ...

  9. Codeforces Round #581 (Div. 2)

    A:暴力. #include<cstdio> #include<cstring> #include<iostream> #include<algorithm& ...

  10. vue中常见的指令

    1,差值表达式{{}} <p >{{ msg }}</p> 2.v-cloak解决差值表达式闪烁的问题 <p v-cloak>{{ msg }}</p> ...