|
@@ -22,12 +22,22 @@ import kotlinx.android.synthetic.main.webciew_lay.*
|
|
|
import org.greenrobot.eventbus.EventBus
|
|
|
import org.greenrobot.eventbus.Subscribe
|
|
|
import org.greenrobot.eventbus.ThreadMode
|
|
|
+import java.lang.reflect.Constructor
|
|
|
+import java.lang.reflect.Field
|
|
|
+import java.lang.reflect.Method
|
|
|
|
|
|
|
|
|
@Router(path = "/callingbed/webview")
|
|
|
class WebviewActivity :BaseActivity<BedWebviewActivityPresenter, WebciewLayBinding>(), BedWebViewActivityContract.View{
|
|
|
private val TAG = "WebviewActivity"
|
|
|
override fun getLayId(): Int {
|
|
|
+ // 解决共用system uid时报
|
|
|
+ // Caused by: java.lang.UnsupportedOperationException: For security reasons, WebView is not allowed in privileged processes 错误
|
|
|
+ val uid = android.os.Process.myUid()
|
|
|
+ if (uid == android.os.Process.ROOT_UID || uid == android.os.Process.SYSTEM_UID) {
|
|
|
+ hookWebView()
|
|
|
+ }
|
|
|
+
|
|
|
return R.layout.webciew_lay
|
|
|
}
|
|
|
|
|
@@ -50,13 +60,72 @@ class WebviewActivity :BaseActivity<BedWebviewActivityPresenter, WebciewLayBindi
|
|
|
if (url!=null && key!=null){
|
|
|
val result = key.replace("&", "&")
|
|
|
Log.d(TAG, "更新后的 url_params_temp 值为:"+url+"?"+result)
|
|
|
- webview.loadUrl(url+"?"+result);
|
|
|
+ webview.loadUrl(url+"?"+result)
|
|
|
}
|
|
|
// webview.loadUrl("https://www.baidu.com/");
|
|
|
//带参数
|
|
|
// webview.loadDataWithBaseURL(HttpConstant.PATH, content, "text/html", "UTF-8", null);
|
|
|
}
|
|
|
|
|
|
+ fun hookWebView() {
|
|
|
+ val sdkInt = Build.VERSION.SDK_INT
|
|
|
+ try {
|
|
|
+ val factoryClass = Class.forName("android.webkit.WebViewFactory")
|
|
|
+ val field: Field = factoryClass.getDeclaredField("sProviderInstance")
|
|
|
+ field.setAccessible(true)
|
|
|
+ var sProviderInstance: Any? = field.get(null)
|
|
|
+ if (sProviderInstance != null) {
|
|
|
+ Log.i(TAG, "sProviderInstance isn't null")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ val getProviderClassMethod: Method
|
|
|
+ if (sdkInt > 22) {
|
|
|
+ getProviderClassMethod = factoryClass.getDeclaredMethod("getProviderClass")
|
|
|
+ } else if (sdkInt == 22) {
|
|
|
+ getProviderClassMethod = factoryClass.getDeclaredMethod("getFactoryClass")
|
|
|
+ } else {
|
|
|
+ Log.i(TAG, "Don't need to Hook WebView")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ getProviderClassMethod.setAccessible(true)
|
|
|
+ val factoryProviderClass = getProviderClassMethod.invoke(factoryClass) as Class<*>
|
|
|
+ val delegateClass = Class.forName("android.webkit.WebViewDelegate")
|
|
|
+ val delegateConstructor: Constructor<*> = delegateClass.getDeclaredConstructor()
|
|
|
+ delegateConstructor.setAccessible(true)
|
|
|
+ if (sdkInt < 26) { //低于Android O版本
|
|
|
+ val providerConstructor: Constructor<*>? =
|
|
|
+ factoryProviderClass.getConstructor(delegateClass)
|
|
|
+ if (providerConstructor != null) {
|
|
|
+ providerConstructor.setAccessible(true)
|
|
|
+ sProviderInstance =
|
|
|
+ providerConstructor.newInstance(delegateConstructor.newInstance())
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ val chromiumMethodName: Field =
|
|
|
+ factoryClass.getDeclaredField("CHROMIUM_WEBVIEW_FACTORY_METHOD")
|
|
|
+ chromiumMethodName.setAccessible(true)
|
|
|
+ var chromiumMethodNameStr = chromiumMethodName.get(null)
|
|
|
+ if (chromiumMethodNameStr == null) {
|
|
|
+ chromiumMethodNameStr = "create"
|
|
|
+ }
|
|
|
+ val staticFactory: Method? =
|
|
|
+ factoryProviderClass.getMethod(chromiumMethodNameStr as String, delegateClass)
|
|
|
+ if (staticFactory != null) {
|
|
|
+ sProviderInstance =
|
|
|
+ staticFactory.invoke(null, delegateConstructor.newInstance())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (sProviderInstance != null) {
|
|
|
+ field.set("sProviderInstance", sProviderInstance)
|
|
|
+ Log.i(TAG, "Hook success!")
|
|
|
+ } else {
|
|
|
+ Log.i(TAG, "Hook failed!")
|
|
|
+ }
|
|
|
+ } catch (e: Throwable) {
|
|
|
+ Log.w(TAG, e)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
override fun bindEvent() {
|
|
|
back_btn.setOnClickListener {
|
|
|
finish()
|
|
@@ -101,9 +170,9 @@ class WebviewActivity :BaseActivity<BedWebviewActivityPresenter, WebciewLayBindi
|
|
|
|
|
|
override fun onBackPressed() {
|
|
|
if (webview.canGoBack()) {
|
|
|
- webview.goBack();
|
|
|
+ webview.goBack()
|
|
|
} else {
|
|
|
- this.finish();
|
|
|
+ this.finish()
|
|
|
}
|
|
|
}
|
|
|
private fun webviewSetting(webSettings: WebSettings) {
|