使用hook 反射调用
class FaqActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStatusNavBarColor(Color.TRANSPARENT, Color.WHITE)
with(window) {
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
}
hookWebView()
setContentView(R.layout.activity_faq)
initView()
}
private fun initView() {
faqWeb.loadUrl("https://www.baidu.com/")
faqWeb.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
return false
}
}
}
fun hookWebView() {
val sdkInt = Build.VERSION.SDK_INT
try {
val factoryClass = Class.forName("android.webkit.WebViewFactory")
val field = factoryClass.getDeclaredField("sProviderInstance")
field.isAccessible = true
var sProviderInstance = field.get(null)
if (sProviderInstance != null) {
Log.i("ww", "sProviderInstance isn't null")
return
}
val getProviderClassMethod: Method
getProviderClassMethod = when {
sdkInt > 22 -> factoryClass.getDeclaredMethod("getProviderClass")
sdkInt == 22 -> factoryClass.getDeclaredMethod("getFactoryClass")
else -> {
Log.i("ww", "Don't need to Hook WebView")
return
}
}
getProviderClassMethod.isAccessible = true
val factoryProviderClass = getProviderClassMethod.invoke(factoryClass) as Class<*>
val delegateClass = Class.forName("android.webkit.WebViewDelegate")
val delegateConstructor = delegateClass.getDeclaredConstructor()
delegateConstructor.isAccessible = true
if (sdkInt < 26) {//低于Android O版本
val providerConstructor = factoryProviderClass.getConstructor(delegateClass)
if (providerConstructor != null) {
providerConstructor.isAccessible = true
sProviderInstance = providerConstructor.newInstance(delegateConstructor.newInstance())
}
} else {
val chromiumMethodName = factoryClass.getDeclaredField("CHROMIUM_WEBVIEW_FACTORY_METHOD")
chromiumMethodName.isAccessible = true
var chromiumMethodNameStr: String? = chromiumMethodName.get(null) as String
if (chromiumMethodNameStr == null) {
chromiumMethodNameStr = "create"
}
val staticFactory = factoryProviderClass.getMethod(chromiumMethodNameStr, delegateClass)
if (staticFactory != null) {
sProviderInstance = staticFactory.invoke(null, delegateConstructor.newInstance())
}
}
if (sProviderInstance != null) {
field.set("sProviderInstance", sProviderInstance)
Log.i("ww", "Hook success!")
} else {
Log.i("ww", "Hook failed!")
}
} catch (e: Throwable) {
Log.w("ww", e)
}
}
}