Android開(kāi)發(fā)系統(tǒng)應(yīng)用(android.uid.system)使用webview報(bào)錯(cuò)For security reasons, WebView is not allowed in privileged processes

原文

現(xiàn)象:

在開(kāi)發(fā)系統(tǒng)級(jí)應(yīng)用的時(shí)候,需要將自己的app在manifest中添加上android:sharedUserId="android.uid.system",此時(shí)如果在app中使用webview應(yīng)用就會(huì)報(bào)錯(cuò)

Caused by: java.lang.UnsupportedOperationException: For security reasons, WebView is not allowed in privileged processes
at android.webkit.WebViewFactory.getProvider(WebViewFactory.java:155)
at android.webkit.CookieManager.getInstance(CookieManager.java:42)

原因:

由于Android的webview在各個(gè)版本改動(dòng)較大,谷歌已經(jīng)將其獨(dú)立出來(lái),作為一個(gè)Android system webviewapp。為了防止影響系統(tǒng)app,谷歌從5.1開(kāi)始全面禁止系統(tǒng)應(yīng)用使用webview。查看源碼獲悉在WebviewFactory代碼中某個(gè)靜態(tài)實(shí)例初始化之前判斷api版本并拋出錯(cuò)誤。
問(wèn)題分析:既然是谷歌禁止,那么要么是欺騙api版本;要么修改源碼。根據(jù)大牛的分析,欺騙API不大可行,反倒是修改源碼,人工給該變量賦值比較靠譜。

問(wèn)題處理:

在使用webview之前,使用hook(鉤子)方法,給該變量賦值。具體代碼如下

private void hookWebView() {
        Class<?> factoryClass = null;
        try {
            factoryClass = Class.forName("android.webkit.WebViewFactory");
            Method getProviderClassMethod = null;
            Object sProviderInstance = null;

            if (Build.VERSION.SDK_INT == 23) {
                getProviderClassMethod = factoryClass.getDeclaredMethod("getProviderClass");
                getProviderClassMethod.setAccessible(true);
                Class<?> providerClass = (Class<?>) getProviderClassMethod.invoke(factoryClass);
                Class<?> delegateClass = Class.forName("android.webkit.WebViewDelegate");
                Constructor<?> constructor = providerClass.getConstructor(delegateClass);
                if (constructor != null) {
                    constructor.setAccessible(true);
                    Constructor<?> constructor2 = delegateClass.getDeclaredConstructor();
                    constructor2.setAccessible(true);
                    sProviderInstance = constructor.newInstance(constructor2.newInstance());
                }
            } else if (Build.VERSION.SDK_INT == 22) {
                getProviderClassMethod = factoryClass.getDeclaredMethod("getFactoryClass");
                getProviderClassMethod.setAccessible(true);
                Class<?> providerClass = (Class<?>) getProviderClassMethod.invoke(factoryClass);
                Class<?> delegateClass = Class.forName("android.webkit.WebViewDelegate");
                Constructor<?> constructor = providerClass.getConstructor(delegateClass);
                if (constructor != null) {
                    constructor.setAccessible(true);
                    Constructor<?> constructor2 = delegateClass.getDeclaredConstructor();
                    constructor2.setAccessible(true);
                    sProviderInstance = constructor.newInstance(constructor2.newInstance());
                }
            } else if (Build.VERSION.SDK_INT == 21) {// Android 21無(wú)WebView安全限制
                getProviderClassMethod = factoryClass.getDeclaredMethod("getFactoryClass");
                getProviderClassMethod.setAccessible(true);
                Class<?> providerClass = (Class<?>) getProviderClassMethod.invoke(factoryClass);
                sProviderInstance = providerClass.newInstance();
            }
            if (sProviderInstance != null) {
                Field field = factoryClass.getDeclaredField("sProviderInstance");
                field.setAccessible(true);
                field.set("sProviderInstance", sProviderInstance);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容