Android webveiw 出现栈错误解决办法
android webveiw 出现栈错误解决办法
前言:
最近做一个项目,项目调试基础库的一个调试工具展示设备信息页面使用webview。有一个应用集成调试基础库展示内容时出现
java.lang.unsupportedoperationexception: for security reasons, webview is not allowed in privileged processes
因为应用是系统级别的,在androidmanifest.xml中添加了android:shareduserid="android.uid.system"
根据exception提示出于安全原因,所以初步断定很可能跟应用为系统应用有很大关系,于是开始了查找代码寻源之旅
首先我们看一下具体的错误堆栈
at android.app.activitythread.performlaunchactivity(activitythread.java:2325) at android.app.activitythread.handlelaunchactivity(activitythread.java:2387) at android.app.activitythread.access$800(activitythread.java:151) at android.app.activitythread$h.handlemessage(activitythread.java:1303) at android.os.handler.dispatchmessage(handler.java:102) at android.os.looper.loop(looper.java:135) at android.app.activitythread.main(activitythread.java:5257) at java.lang.reflect.method.invoke(native method) at java.lang.reflect.method.invoke(method.java:372) at com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:955) at com.android.internal.os.zygoteinit.main(zygoteinit.java:750) aused by: android.view.inflateexception: binary xml file line #17: error inflating class android.webkit.webview at android.view.layoutinflater.createview(layoutinflater.java:633) at com.android.internal.policy.impl.phonelayoutinflater.oncreateview(phonelayoutinflater.java:55) at android.view.layoutinflater.oncreateview(layoutinflater.java:682) at android.view.layoutinflater.createviewfromtag(layoutinflater.java:741) at android.view.layoutinflater.rinflate(layoutinflater.java:806) at android.view.layoutinflater.inflate(layoutinflater.java:504) at android.view.layoutinflater.inflate(layoutinflater.java:414) at android.view.layoutinflater.inflate(layoutinflater.java:365) at com.android.internal.policy.impl.phonewindow.setcontentview(phonewindow.java:379) at android.app.activity.setcontentview(activity.java:2145) at com.mipt.store.activity.infoactivity.oncreate(unknown source) at android.app.activity.performcreate(activity.java:5990) at android.app.instrumentation.callactivityoncreate(instrumentation.java:1106) at android.app.activitythread.performlaunchactivity(activitythread.java:2278) ... 10 more aused by: java.lang.reflect.invocationtargetexception at java.lang.reflect.constructor.newinstance(native method) at java.lang.reflect.constructor.newinstance(constructor.java:288) at android.view.layoutinflater.createview(layoutinflater.java:607) ... 23 more aused by: java.lang.unsupportedoperationexception: for security reasons, webview is not allowed in privileged processes at android.webkit.webviewfactory.getprovider(webviewfactory.java:96) at android.webkit.webview.getfactory(webview.java:2194) at android.webkit.webview.ensureprovidercreated(webview.java:2189) at android.webkit.webview.setoverscrollmode(webview.java:2248) at android.view.view.<init>(view.java:3588) at android.view.view.<init>(view.java:3682) at android.view.viewgroup.<init>(viewgroup.java:497) at android.widget.absolutelayout.<init>(absolutelayout.java:55) at android.webkit.webview.<init>(webview.java:544) at android.webkit.webview.<init>(webview.java:489) at android.webkit.webview.<init>(webview.java:472) at android.webkit.webview.<init>(webview.java:459) ... 26 more
错误提示显示为“caused by: java.lang.unsupportedoperationexception: for security reasons, webview is not allowed in privileged processes”
security reasons即安全原因。为了查明原因直接查看android源码。经过一番查找,发现抛出exception的在
frameworks/base/master/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; 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 { class<webviewfactoryprovider> providerclass = getproviderclass(); trace.tracebegin(trace.trace_tag_webview, "providerclass.newinstance()"); try { 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); } } }
webview在初始化的时候会检查初始化进程的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"); }
如果进程id是root或者system,就会抛出unsupportedoperationexception。为什么会有这种安全机制呢?因为webview允许运行js,如果用户通过js注入安全代码,那么js就可以肆无忌惮的使用系统权限,这无疑是一个漏洞,可谓门户大开。
果不其然就是android:shareduserid="android.uid.system"的问题,因为是系统应用所以只能修改基础调试库的展示控件,把展示调试信息的webview改为textview。
感谢阅读,希望能通过本文帮助到大家,谢谢大家对本站的支持,如有疑问请留言或者到本站社区交流讨论,大家共同进步!
推荐阅读
-
Android webveiw 出现栈错误解决办法
-
Android 中读取SD卡文件时抛出NullPointerException错误解决办法
-
Android Data Binding 在 library module 中遇到错误及解决办法
-
更新iTunes出现错误怎么办 iTunes更新出现错误现象的解决办法
-
mysql “ Every derived table must have its own alias”出现错误解决办法
-
Android 软键盘出现不适应的解决办法总结
-
IE浏览器报错出现“网页上有错误”提示的解决办法
-
PHP Curl出现403错误的解决办法
-
Android 出现:java.lang.NoClassDefFoundError...错误解决办法
-
Android DaggerActivityComponent错误解决办法详解