java.lang.UnsupportedOperationExceptionが:によって引き起こさ:セキュリティの脆弱性のWebViewのの、システム・アプリケーションのWebViewの使用に関する一般的な禁止からGoogleの5.1は、使用がエラークラッシュするアプリケーションの原因となるため、セキュリティ上の理由から、WebViewのを見ることができる特権例外メッセージプロセスに許可されていませんgetProvider方法でWebViewFactory.javaスロー。フレームワークのソースパス/ベース/コア/ javaの/アンドロイド/ WebKitの/ WebViewFactory.java
静的WebViewFactoryProvider getProvider(){ (sProviderLock)同期{ //ここでは、この機能(および工場の抽象化)の主な目的は、維持することです 正直//私たちをして、プロキシをバインドするときWebViewの内部の使用を最小限に抑えます。 (もし!sProviderInstance = null)の戻りsProviderInstance。//如果sProviderInstance不为空直接返回 // 1、判断、是如果ID系统、则抛出异常。 最終INT UID = android.os.Process.myUid()。 IF(UID == android.os.Process.ROOT_UID || UID == android.os.Process.SYSTEM_UID){ 新しいUnsupportedOperationExceptionが(スロー StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads()。 "セキュリティ上の理由から、WebViewのは、特権プロセスでは許可されていません"); } Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW、 "WebViewFactory.getProvider()")。 {試みる // 2 クラス<WebViewFactoryProvider> providerClass = getProviderClass()。 Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW、 "providerClass.newInstance()"); 試す{ // 3给sProviderInstance赋值 sProviderInstance = providerClass.getConstructor(WebViewDelegate.class) .newInstance(新しいWebViewDelegate())。 IF(DEBUG)Log.v(LOGTAG、 "ロードプロバイダ:" + sProviderInstance)。 sProviderInstanceを返します。 }キャッチ(例外e){ Log.e(LOGTAG、 "エラーインスタンス化プロバイダ"、E)。 新しいAndroidRuntimeException(e)を投げます。 }最後に{ Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW)。 } }最後に{ Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW)。 StrictMode.setThreadPolicy(oldPolicy)。 } } }
システムIDた場合は、例外を投げる!反射によってWebViewのを呼び出す前に、sProviderInstanceの割り当てに、あなたは、アプリケーションでメソッドを呼び出すことができるように、互換性のある8.0を
パブリック静的ボイドhookWebView(){ int型sdkInt = Build.VERSION.SDK_INT。 試す{ クラスfactoryClass = Class.forNameの( "android.webkit.WebViewFactory")<?>; フィールドフィールド= factoryClass.getDeclaredField( "sProviderInstance")。 field.setAccessible(真の); オブジェクトsProviderInstance = field.get(NULL)。 (!sProviderInstance = NULL){場合 Log.iは(TAGは、 "sProviderInstanceがnullではありません"); 返します。 } メソッドgetProviderClassMethod。 (sdkInt> 22){もし getProviderClassMethod = factoryClass.getDeclaredMethod( "getProviderClass")。 }そうであれば(sdkInt == 22){ getProviderClassMethod = factoryClass。 }他{ Log.i(TAG、 "WebViewのをフックする必要はありません"); 返します。 } getProviderClassMethod.setAccessible(TRUE)。 クラスfactoryProviderClass =(クラス<?>)getProviderClassMethod.invoke(factoryClass)<?>; <?>クラスdelegateClass = Class.forNameの( "android.webkit.WebViewDelegate"); コンストラクタdelegateConstructor = delegateClass.getDeclaredConstructor()<?>; } }他{ delegateConstructor.setAccessible(真の); IF(sdkInt <26){//低于アンドロイドO版本 コンストラクタ<> providerConstructor = factoryProviderClass.getConstructor(delegateClass);? (!providerConstructor = NULL){もし providerConstructor.setAccessible(真の); sProviderInstance = providerConstructor.newInstance(delegateConstructor.newInstance())。 フィールドchromiumMethodName = factoryClass.getDeclaredField( "CHROMIUM_WEBVIEW_FACTORY_METHOD")。 chromiumMethodName.setAccessible(真の); ストリングchromiumMethodNameStr =(文字列)chromiumMethodName.get(NULL)。 IF(chromiumMethodNameStr == NULL){ chromiumMethodNameStrは= "作成"。 } メソッドstaticFactory = factoryProviderClass.getMethod(chromiumMethodNameStr、delegateClass)。 もし(staticFactory!= NULL){ sProviderInstance = staticFactory.invoke(ヌル、delegateConstructor.newInstance())。 } } もし(!sProviderInstance = NULL){ field.set( "sProviderInstance"、sProviderInstance)。 Log.i(TAG、 "フック成功!"); }他{ Log.i(TAG、 "フックが失敗しました!"); } }キャッチ(ThrowableをE){ Log.w(TAG、E)。 } }