欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android webveiw 出现栈错误解决办法

程序员文章站 2023-12-04 12:32:52
android webveiw 出现栈错误解决办法 前言: 最近做一个项目,项目调试基础库的一个调试工具展示设备信息页面使用webview。有一个应用集成调试基础库展示...

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。

感谢阅读,希望能通过本文帮助到大家,谢谢大家对本站的支持,如有疑问请留言或者到本站社区交流讨论,大家共同进步!