Android webveiw 出现栈错误解决办法
Androidwebveiw出现栈错误解决办法
前言:
最近做一个项目,项目调试基础库的一个调试工具展示设备信息页面使用WebView。有一个应用集成调试基础库展示内容时出现
java.lang.UnsupportedOperationException:Forsecurityreasons,WebViewisnotallowedinprivilegedprocesses
因为应用是系统级别的,在AndroidManifest.xml中添加了android:sharedUserId="android.uid.system"
根据exception提示出于安全原因,所以初步断定很可能跟应用为系统应用有很大关系,于是开始了查找代码寻源之旅
首先我们看一下具体的错误堆栈
atandroid.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325) atandroid.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387) atandroid.app.ActivityThread.access$800(ActivityThread.java:151) atandroid.app.ActivityThread$H.handleMessage(ActivityThread.java:1303) atandroid.os.Handler.dispatchMessage(Handler.java:102) atandroid.os.Looper.loop(Looper.java:135) atandroid.app.ActivityThread.main(ActivityThread.java:5257) atjava.lang.reflect.Method.invoke(NativeMethod) atjava.lang.reflect.Method.invoke(Method.java:372) atcom.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:955) atcom.android.internal.os.ZygoteInit.main(ZygoteInit.java:750) ausedby:android.view.InflateException:BinaryXMLfileline#17:Errorinflatingclassandroid.webkit.WebView atandroid.view.LayoutInflater.createView(LayoutInflater.java:633) atcom.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55) atandroid.view.LayoutInflater.onCreateView(LayoutInflater.java:682) atandroid.view.LayoutInflater.createViewFromTag(LayoutInflater.java:741) atandroid.view.LayoutInflater.rInflate(LayoutInflater.java:806) atandroid.view.LayoutInflater.inflate(LayoutInflater.java:504) atandroid.view.LayoutInflater.inflate(LayoutInflater.java:414) atandroid.view.LayoutInflater.inflate(LayoutInflater.java:365) atcom.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:379) atandroid.app.Activity.setContentView(Activity.java:2145) atcom.mipt.store.activity.InfoActivity.onCreate(UnknownSource) atandroid.app.Activity.performCreate(Activity.java:5990) atandroid.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106) atandroid.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278) ...10more ausedby:java.lang.reflect.InvocationTargetException atjava.lang.reflect.Constructor.newInstance(NativeMethod) atjava.lang.reflect.Constructor.newInstance(Constructor.java:288) atandroid.view.LayoutInflater.createView(LayoutInflater.java:607) ...23more ausedby:java.lang.UnsupportedOperationException:Forsecurityreasons,WebViewisnotallowedinprivilegedprocesses atandroid.webkit.WebViewFactory.getProvider(WebViewFactory.java:96) atandroid.webkit.WebView.getFactory(WebView.java:2194) atandroid.webkit.WebView.ensureProviderCreated(WebView.java:2189) atandroid.webkit.WebView.setOverScrollMode(WebView.java:2248) atandroid.view.View.(View.java:3588) atandroid.view.View. (View.java:3682) atandroid.view.ViewGroup. (ViewGroup.java:497) atandroid.widget.AbsoluteLayout. (AbsoluteLayout.java:55) atandroid.webkit.WebView. (WebView.java:544) atandroid.webkit.WebView. (WebView.java:489) atandroid.webkit.WebView. (WebView.java:472) atandroid.webkit.WebView. (WebView.java:459) ...26more
错误提示显示为“Causedby:java.lang.UnsupportedOperationException:Forsecurityreasons,WebViewisnotallowedinprivilegedprocesses”
securityreasons即安全原因。为了查明原因直接查看android源码。经过一番查找,发现抛出Exception的在
frameworks/base/master/core/java/android/webkit/WebViewFactory.java
staticWebViewFactoryProvidergetProvider(){ synchronized(sProviderLock){ //Fornowthemainpurposeofthisfunction(andthefactoryabstraction)istokeep //ushonestandminimizeusageofWebViewinternalswhenbindingtheproxy. if(sProviderInstance!=null)returnsProviderInstance; finalintuid=android.os.Process.myUid(); if(uid==android.os.Process.ROOT_UID||uid==android.os.Process.SYSTEM_UID){ thrownewUnsupportedOperationException( "Forsecurityreasons,WebViewisnotallowedinprivilegedprocesses"); } StrictMode.ThreadPolicyoldPolicy=StrictMode.allowThreadDiskReads(); Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW,"WebViewFactory.getProvider()"); try{ ClassproviderClass=getProviderClass(); Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW,"providerClass.newInstance()"); try{ sProviderInstance=providerClass.getConstructor(WebViewDelegate.class) .newInstance(newWebViewDelegate()); if(DEBUG)Log.v(LOGTAG,"Loadedprovider:"+sProviderInstance); returnsProviderInstance; }catch(Exceptione){ Log.e(LOGTAG,"errorinstantiatingprovider",e); thrownewAndroidRuntimeException(e); }finally{ Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); } }finally{ Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); StrictMode.setThreadPolicy(oldPolicy); } } }
WebView在初始化的时候会检查初始化进程的id.
finalintuid=android.os.Process.myUid(); if(uid==android.os.Process.ROOT_UID||uid==android.os.Process.SYSTEM_UID){ thrownewUnsupportedOperationException( "Forsecurityreasons,WebViewisnotallowedinprivilegedprocesses"); }
如果进程ID是root或者system,就会抛出UnsupportedOperationException。为什么会有这种安全机制呢?因为webview允许运行js,如果用户通过js注入安全代码,那么js就可以肆无忌惮的使用系统权限,这无疑是一个漏洞,可谓门户大开。
果不其然就是android:sharedUserId="android.uid.system"的问题,因为是系统应用所以只能修改基础调试库的展示控件,把展示调试信息的webview改为textview。
感谢阅读,希望能通过本文帮助到大家,谢谢大家对本站的支持,如有疑问请留言或者到本站社区交流讨论,大家共同进步!