Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DiDi
DoraemonKit
提交
d07ceb32
D
DoraemonKit
项目概览
DiDi
/
DoraemonKit
10 个月 前同步成功
通知
166
Star
19623
Fork
3062
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
DoraemonKit
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
d07ceb32
编写于
9月 04, 2020
作者:
J
jackjintai
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
android:新增tencent x5 WebView的 网络拦截
上级
a5574650
变更
22
隐藏空白更改
内联
并排
Showing
22 changed file
with
810 addition
and
56 deletion
+810
-56
Android/java/app/build.gradle
Android/java/app/build.gradle
+2
-0
Android/java/app/src/debug/java/com/didichuxing/doraemondemo/MainDebugActivity.kt
...ug/java/com/didichuxing/doraemondemo/MainDebugActivity.kt
+3
-1
Android/java/app/src/main/AndroidManifest.xml
Android/java/app/src/main/AndroidManifest.xml
+2
-1
Android/java/app/src/main/java/com/didichuxing/doraemondemo/WebViewNormalActivity.kt
...ava/com/didichuxing/doraemondemo/WebViewNormalActivity.kt
+5
-5
Android/java/app/src/main/java/com/didichuxing/doraemondemo/WebViewX5Activity.kt
...in/java/com/didichuxing/doraemondemo/WebViewX5Activity.kt
+91
-0
Android/java/app/src/main/res/layout/activity_main.xml
Android/java/app/src/main/res/layout/activity_main.xml
+8
-1
Android/java/app/src/main/res/layout/activity_normal_webview.xml
.../java/app/src/main/res/layout/activity_normal_webview.xml
+15
-0
Android/java/app/src/main/res/layout/activity_x5_webview.xml
Android/java/app/src/main/res/layout/activity_x5_webview.xml
+4
-3
Android/java/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt
...kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt
+21
-8
Android/java/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt
.../kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt
+2
-0
Android/java/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/CommTransformer.kt
...ng/doraemonkit/plugin/classtransformer/CommTransformer.kt
+12
-5
Android/java/config.gradle
Android/java/config.gradle
+4
-2
Android/java/doraemonkit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt
...kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt
+21
-8
Android/java/doraemonkit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt
.../kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt
+2
-0
Android/java/doraemonkit/build.gradle
Android/java/doraemonkit/build.gradle
+4
-1
Android/java/doraemonkit/src/main/java/com/didichuxing/doraemonkit/aop/WebViewHook.java
...ain/java/com/didichuxing/doraemonkit/aop/WebViewHook.java
+35
-11
Android/java/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/DokitWebViewClient.kt
...didichuxing/doraemonkit/kit/h5_help/DokitWebViewClient.kt
+9
-4
Android/java/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/DokitX5WebViewClient.kt
...dichuxing/doraemonkit/kit/h5_help/DokitX5WebViewClient.kt
+465
-0
Android/java/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/H5DokitView.kt
...va/com/didichuxing/doraemonkit/kit/h5_help/H5DokitView.kt
+5
-1
Android/java/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/JsHttpUtil.kt
...ava/com/didichuxing/doraemonkit/kit/h5_help/JsHttpUtil.kt
+88
-3
Android/java/doraemonkit/src/main/res/layout/dk_float_h5_info.xml
...java/doraemonkit/src/main/res/layout/dk_float_h5_info.xml
+9
-0
Android/java/gradle.properties
Android/java/gradle.properties
+3
-2
未找到文件。
Android/java/app/build.gradle
浏览文件 @
d07ceb32
...
...
@@ -146,6 +146,8 @@ dependencies {
// debugImplementation rootProject.ext.dependencies["leakcanary-android"]
//百度地图定位
implementation
files
(
'libs/BaiduLBS_Android.jar'
)
//腾讯x5
implementation
rootProject
.
ext
.
dependencies
[
"tbs"
]
// implementation 'com.aliyun.ams:alicloud-android-hotfix:3.2.12'
}
...
...
Android/java/app/src/debug/java/com/didichuxing/doraemondemo/MainDebugActivity.kt
浏览文件 @
d07ceb32
...
...
@@ -101,6 +101,7 @@ class MainDebugActivity : BaseActivity(), View.OnClickListener {
tvEnv
.
text
=
"${getString(R.string.app_build_types)}:Debug"
btn_jump
.
setOnClickListener
(
this
)
btn_webview
.
setOnClickListener
(
this
)
btn_x5_webview
.
setOnClickListener
(
this
)
findViewById
<
View
>(
R
.
id
.
btn_method_cost
).
setOnClickListener
(
this
)
findViewById
<
View
>(
R
.
id
.
btn_jump_leak
).
setOnClickListener
(
this
)
findViewById
<
View
>(
R
.
id
.
btn_app_launch_stack
).
setOnClickListener
(
this
)
...
...
@@ -298,7 +299,8 @@ class MainDebugActivity : BaseActivity(), View.OnClickListener {
R
.
id
.
btn_show_tool_panel
->
//直接调起工具面板
DoraemonKit
.
showToolPanel
()
R
.
id
.
btn_jump
->
startActivity
(
Intent
(
this
,
SecondActivity
::
class
.
java
))
R
.
id
.
btn_webview
->
startActivity
(
Intent
(
this
,
WebViewActivity
::
class
.
java
))
R
.
id
.
btn_webview
->
startActivity
(
Intent
(
this
,
WebViewNormalActivity
::
class
.
java
))
R
.
id
.
btn_x5_webview
->
startActivity
(
Intent
(
this
,
WebViewX5Activity
::
class
.
java
))
R
.
id
.
btn_jump_leak
->
startActivity
(
Intent
(
this
,
LeakActivity
::
class
.
java
))
R
.
id
.
btn_app_launch_stack
->
{
//MethodStackUtil.getInstance().toJson()
...
...
Android/java/app/src/main/AndroidManifest.xml
浏览文件 @
d07ceb32
...
...
@@ -43,7 +43,8 @@
android:theme=
"@style/AppTheme"
tools:ignore=
"GoogleAppIndexingWarning"
>
<activity
android:name=
".WebViewActivity"
/>
<activity
android:name=
".WebViewNormalActivity"
/>
<activity
android:name=
".WebViewX5Activity"
/>
<activity
android:name=
".SecondActivity"
/>
<activity
android:name=
".LeakActivity"
/>
...
...
Android/java/app/src/main/java/com/didichuxing/doraemondemo/WebViewActivity.kt
→
Android/java/app/src/main/java/com/didichuxing/doraemondemo/WebView
Normal
Activity.kt
浏览文件 @
d07ceb32
...
...
@@ -10,20 +10,20 @@ import androidx.appcompat.app.AppCompatActivity
/**
* Created by wanglikun on 2018/11/13.
*/
class
WebViewActivity
:
AppCompatActivity
()
{
class
WebView
Normal
Activity
:
AppCompatActivity
()
{
val
TAG
=
"WebViewActivity"
// val url = "file:///android_asset/dokit_index.html"
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
setContentView
(
R
.
layout
.
activity_webview
)
val
webView
=
findViewById
<
WebView
>(
R
.
id
.
web_view
)
setContentView
(
R
.
layout
.
activity_
normal_
webview
)
val
webView
=
findViewById
<
WebView
>(
R
.
id
.
normal_
web_view
)
initWebView
(
webView
)
// webView.loadUrl("https://page-daily.kuaidadi.com/m/ddPage_0sTyVhyq.html")
// WebViewHook.inject(webView)
//webView.loadUrl(url)
webView
.
loadUrl
(
"file:///android_asset/dokit_index.html"
)
//
webView.loadUrl("https://www.dokit.cn")
//
webView.loadUrl("file:///android_asset/dokit_index.html")
webView
.
loadUrl
(
"https://www.dokit.cn"
)
// webView.loadUrl("http://xingyun.xiaojukeji.com/docs/dokit/#/intro")
}
...
...
Android/java/app/src/main/java/com/didichuxing/doraemondemo/WebViewX5Activity.kt
0 → 100644
浏览文件 @
d07ceb32
package
com.didichuxing.doraemondemo
import
android.annotation.SuppressLint
import
android.os.Build
import
android.os.Bundle
import
androidx.annotation.RequiresApi
import
androidx.appcompat.app.AppCompatActivity
import
com.tencent.smtt.export.external.interfaces.ConsoleMessage
import
com.tencent.smtt.export.external.interfaces.WebResourceRequest
import
com.tencent.smtt.export.external.interfaces.WebResourceResponse
import
com.tencent.smtt.sdk.WebChromeClient
import
com.tencent.smtt.sdk.WebSettings
import
com.tencent.smtt.sdk.WebView
import
com.tencent.smtt.sdk.WebViewClient
/**
* Created by wanglikun on 2018/11/13.
*/
class
WebViewX5Activity
:
AppCompatActivity
()
{
val
TAG
=
"WebViewActivity"
// val url = "file:///android_asset/dokit_index.html"
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
setContentView
(
R
.
layout
.
activity_x5_webview
)
val
webView
=
findViewById
<
WebView
>(
R
.
id
.
x5_web_view
)
initWebView
(
webView
)
// webView.loadUrl("https://page-daily.kuaidadi.com/m/ddPage_0sTyVhyq.html")
// WebViewHook.inject(webView)
//webView.loadUrl(url)
// webView.loadUrl("file:///android_asset/dokit_index.html")
webView
.
loadUrl
(
"https://www.dokit.cn"
)
// webView.loadUrl("http://xingyun.xiaojukeji.com/docs/dokit/#/intro")
}
@SuppressLint
(
"JavascriptInterface"
)
private
fun
initWebView
(
webView
:
WebView
)
{
val
webSettings
:
WebSettings
=
webView
.
settings
webSettings
.
pluginState
=
WebSettings
.
PluginState
.
ON
webSettings
.
javaScriptEnabled
=
true
webSettings
.
allowFileAccess
=
false
webSettings
.
loadsImagesAutomatically
=
true
webSettings
.
useWideViewPort
=
true
webSettings
.
builtInZoomControls
=
false
webSettings
.
defaultTextEncodingName
=
"UTF-8"
webSettings
.
domStorageEnabled
=
true
webSettings
.
cacheMode
=
WebSettings
.
LOAD_DEFAULT
webSettings
.
javaScriptCanOpenWindowsAutomatically
=
false
webSettings
.
setAllowFileAccessFromFileURLs
(
true
)
webSettings
.
setAllowUniversalAccessFromFileURLs
(
true
)
if
(
Build
.
VERSION
.
SDK_INT
<
Build
.
VERSION_CODES
.
JELLY_BEAN_MR2
)
{
webSettings
.
setRenderPriority
(
WebSettings
.
RenderPriority
.
HIGH
)
}
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
KITKAT
)
{
WebView
.
setWebContentsDebuggingEnabled
(
true
)
}
if
(
Build
.
VERSION
.
SDK_INT
>
Build
.
VERSION_CODES
.
GINGERBREAD_MR1
&&
Build
.
VERSION
.
SDK_INT
<
Build
.
VERSION_CODES
.
JELLY_BEAN_MR1
)
{
webView
.
removeJavascriptInterface
(
"searchBoxJavaBridge_"
)
webView
.
removeJavascriptInterface
(
"accessibilityTraversal"
)
webView
.
removeJavascriptInterface
(
"accessibility"
)
}
webView
.
webViewClient
=
object
:
WebViewClient
()
{
override
fun
shouldOverrideUrlLoading
(
view
:
WebView
,
url
:
String
):
Boolean
{
view
.
loadUrl
(
url
)
return
true
}
@RequiresApi
(
Build
.
VERSION_CODES
.
LOLLIPOP
)
override
fun
shouldInterceptRequest
(
view
:
WebView
?,
request
:
WebResourceRequest
?
):
WebResourceResponse
?
{
return
super
.
shouldInterceptRequest
(
view
,
request
)
}
}
webView
.
webChromeClient
=
object
:
WebChromeClient
()
{
override
fun
onConsoleMessage
(
consoleMessage
:
ConsoleMessage
?):
Boolean
{
//LogHelper.i(TAG, "consoleMessage===>${consoleMessage?.message()}")
return
super
.
onConsoleMessage
(
consoleMessage
)
}
}
}
}
\ No newline at end of file
Android/java/app/src/main/res/layout/activity_main.xml
浏览文件 @
d07ceb32
...
...
@@ -45,7 +45,14 @@
android:id=
"@+id/btn_webview"
android:layout_width=
"match_parent"
android:layout_height=
"50dp"
android:text=
"WebView"
android:text=
"NormalWebView"
android:textAllCaps=
"false"
/>
<Button
android:id=
"@+id/btn_x5_webview"
android:layout_width=
"match_parent"
android:layout_height=
"50dp"
android:text=
"X5WebView"
android:textAllCaps=
"false"
/>
<Button
...
...
Android/java/app/src/main/res/layout/activity_normal_webview.xml
0 → 100644
浏览文件 @
d07ceb32
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:orientation=
"vertical"
tools:context=
"com.didichuxing.doraemondemo.WebViewNormalActivity"
>
<com.didichuxing.doraemonkit.widget.webview.MyWebView
android:id=
"@+id/normal_web_view"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
/>
</LinearLayout>
\ No newline at end of file
Android/java/app/src/main/res/layout/activity_webview.xml
→
Android/java/app/src/main/res/layout/activity_
x5_
webview.xml
浏览文件 @
d07ceb32
...
...
@@ -4,10 +4,11 @@
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
tools:context=
"com.didichuxing.doraemondemo.WebViewActivity"
>
android:orientation=
"vertical"
tools:context=
"com.didichuxing.doraemondemo.WebViewX5Activity"
>
<WebView
android:id=
"@+id/web_view"
<
com.tencent.smtt.sdk.
WebView
android:id=
"@+id/
x5_
web_view"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
/>
...
...
Android/java/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt
浏览文件 @
d07ceb32
...
...
@@ -28,6 +28,11 @@ object DoKitExtUtil {
*/
var
STACK_METHOD_LEVEL
=
5
/**
* 自定义webview全限定名
*/
var
WEBVIEW_CLASS_NAME
:
String
=
""
/**
* 慢函数默认关闭
*/
...
...
@@ -149,8 +154,8 @@ object DoKitExtUtil {
* 白名单
*/
private
val
whitePackageNames
=
arrayOf
(
"com.didichuxing.doraemonkit.DoraemonKit"
,
"com.didichuxing.doraemonkit.DoraemonKitReal"
"com.didichuxing.doraemonkit.DoraemonKit"
,
"com.didichuxing.doraemonkit.DoraemonKitReal"
)
...
...
@@ -158,14 +163,22 @@ object DoKitExtUtil {
* 黑名单
*/
private
val
blackPackageNames
=
arrayOf
(
"com.didichuxing.doraemonkit."
,
"kotlin."
,
"java."
,
"android."
,
"androidx."
"com.didichuxing.doraemonkit."
,
"kotlin."
,
"java."
,
"android."
,
"androidx."
)
fun
log
(
tag
:
String
,
className
:
String
,
methodName
:
String
,
access
:
Int
,
desc
:
String
,
signature
:
String
,
thresholdTime
:
Int
)
{
fun
log
(
tag
:
String
,
className
:
String
,
methodName
:
String
,
access
:
Int
,
desc
:
String
,
signature
:
String
,
thresholdTime
:
Int
)
{
if
(
DOKIT_LOG_SWITCH
)
{
println
(
"$tag===matched====> className===$className methodName===$methodName access===$access desc===$desc signature===$signature thresholdTime===$thresholdTime"
)
}
...
...
Android/java/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt
浏览文件 @
d07ceb32
...
...
@@ -76,11 +76,13 @@ class DoKitPlugin : Plugin<Project> {
val
slowMethodSwitch
=
project
.
getProperty
(
"DOKIT_METHOD_SWITCH"
,
false
)
val
slowMethodStrategy
=
project
.
getProperty
(
"DOKIT_METHOD_STRATEGY"
,
0
)
val
methodStackLevel
=
project
.
getProperty
(
"DOKIT_METHOD_STACK_LEVEL"
,
5
)
val
webViewClassName
=
project
.
getProperty
(
"DOKIT_WEBVIEW_CLASS_NAME"
,
""
)
DoKitExtUtil
.
DOKIT_PLUGIN_SWITCH
=
pluginSwitch
DoKitExtUtil
.
DOKIT_LOG_SWITCH
=
logSwitch
DoKitExtUtil
.
SLOW_METHOD_SWITCH
=
slowMethodSwitch
DoKitExtUtil
.
SLOW_METHOD_STRATEGY
=
slowMethodStrategy
DoKitExtUtil
.
STACK_METHOD_LEVEL
=
methodStackLevel
DoKitExtUtil
.
WEBVIEW_CLASS_NAME
=
webViewClassName
"application module ${project.name} is executing..."
.
println
()
...
...
Android/java/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/CommTransformer.kt
浏览文件 @
d07ceb32
...
...
@@ -155,15 +155,16 @@ class CommTransformer : ClassTransformer {
//webView 字节码操作
if
(
DoKitExtUtil
.
commExt
.
webViewSwitch
)
{
//普通的webview
klass
.
methods
.
forEach
{
method
->
method
.
instructions
?.
iterator
()
?.
asIterable
()
?.
filterIsInstance
(
MethodInsnNode
::
class
.
java
)
?.
filter
{
it
.
opcode
==
INVOKEVIRTUAL
&&
it
.
owner
==
"android/webkit/WebView"
&&
it
.
name
==
"loadUrl"
&&
it
.
desc
==
"(Ljava/lang/String;)V"
it
.
desc
==
"(Ljava/lang/String;)V"
&&
isWebViewOwnerNameMatched
(
it
.
owner
)
}
?.
forEach
{
"${context.projectDir.lastPath()}->hook WebView#loadurl method succeed in : ${className}_${method.name}_${method.desc}"
.
println
()
"${context.projectDir.lastPath()}->hook WebView#loadurl method succeed in : ${className}_${method.name}_${method.desc}
| ${it.owner}
"
.
println
()
method
.
instructions
.
insertBefore
(
it
,
createWebViewInsnList
()
...
...
@@ -172,7 +173,6 @@ class CommTransformer : ClassTransformer {
}
}
// url connection
klass
.
methods
.
forEach
{
method
->
method
.
instructions
?.
iterator
()
?.
asIterable
()
...
...
@@ -195,6 +195,13 @@ class CommTransformer : ClassTransformer {
return
klass
}
private
fun
isWebViewOwnerNameMatched
(
ownerName
:
String
):
Boolean
{
return
ownerName
==
"android/webkit/WebView"
||
ownerName
==
"com/tencent/smtt/sdk/WebView"
||
ownerName
.
contentEquals
(
"WebView"
)
||
ownerName
==
DoKitExtUtil
.
WEBVIEW_CLASS_NAME
}
/**
* 创建pluginConfig代码指令
...
...
@@ -647,7 +654,7 @@ class CommTransformer : ClassTransformer {
INVOKESTATIC
,
"com/didichuxing/doraemonkit/aop/WebViewHook"
,
"inject"
,
"(L
android/webkit/WebView
;)V"
,
"(L
java/lang/Object
;)V"
,
false
)
)
...
...
Android/java/config.gradle
浏览文件 @
d07ceb32
...
...
@@ -38,7 +38,7 @@ ext {
"design"
:
'com.google.android.material:material:1.1.0'
,
"kotlin"
:
"org.jetbrains.kotlin:kotlin-stdlib-jdk7:${android["
kotlin_version
"]}"
,
"core-ktx"
:
"androidx.core:core-ktx:1.3.0"
,
"web
view"
:
"androidx.webkit:webkit:1.1
.0"
,
"web
kit"
:
"androidx.webkit:webkit:1.3
.0"
,
//constraintLayout
"constraintLayout"
:
'androidx.constraintlayout:constraintlayout:1.1.3'
,
"coroutines-core"
:
"org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7"
,
...
...
@@ -105,7 +105,9 @@ ext {
//跨进程通信框架
"abridge"
:
"com.sjtu.yifei:abridge:1.0.1"
,
"jsoup"
:
"org.jsoup:jsoup:1.13.1"
,
"mimecraft"
:
"com.squareup.mimecraft:mimecraft:1.1.1"
"mimecraft"
:
"com.squareup.mimecraft:mimecraft:1.1.1"
,
//tencent x5 浏览器 https://x5.tencent.com/
"tbs"
:
"com.tencent.tbs.tbssdk:sdk:43903"
,
// "swipeback" : "me.imid.swipebacklayout.lib:library:1.1.0"
]
...
...
Android/java/doraemonkit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt
浏览文件 @
d07ceb32
...
...
@@ -28,6 +28,11 @@ object DoKitExtUtil {
*/
var
STACK_METHOD_LEVEL
=
5
/**
* webview 的全限定名
*/
var
WEBVIEW_CLASS_NAME
=
""
/**
* 慢函数默认关闭
*/
...
...
@@ -149,8 +154,8 @@ object DoKitExtUtil {
* 白名单
*/
private
val
whitePackageNames
=
arrayOf
(
"com.didichuxing.doraemonkit.DoraemonKit"
,
"com.didichuxing.doraemonkit.DoraemonKitReal"
"com.didichuxing.doraemonkit.DoraemonKit"
,
"com.didichuxing.doraemonkit.DoraemonKitReal"
)
...
...
@@ -158,14 +163,22 @@ object DoKitExtUtil {
* 黑名单
*/
private
val
blackPackageNames
=
arrayOf
(
"com.didichuxing.doraemonkit."
,
"kotlin."
,
"java."
,
"android."
,
"androidx."
"com.didichuxing.doraemonkit."
,
"kotlin."
,
"java."
,
"android."
,
"androidx."
)
fun
log
(
tag
:
String
,
className
:
String
,
methodName
:
String
,
access
:
Int
,
desc
:
String
,
signature
:
String
,
thresholdTime
:
Int
)
{
fun
log
(
tag
:
String
,
className
:
String
,
methodName
:
String
,
access
:
Int
,
desc
:
String
,
signature
:
String
,
thresholdTime
:
Int
)
{
if
(
DOKIT_LOG_SWITCH
)
{
println
(
"$tag===matched====> className===$className methodName===$methodName access===$access desc===$desc signature===$signature thresholdTime===$thresholdTime"
)
}
...
...
Android/java/doraemonkit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt
浏览文件 @
d07ceb32
...
...
@@ -76,11 +76,13 @@ class DoKitPlugin : Plugin<Project> {
val
slowMethodSwitch
=
project
.
getProperty
(
"DOKIT_METHOD_SWITCH"
,
false
)
val
slowMethodStrategy
=
project
.
getProperty
(
"DOKIT_METHOD_STRATEGY"
,
0
)
val
methodStackLevel
=
project
.
getProperty
(
"DOKIT_METHOD_STACK_LEVEL"
,
5
)
val
webviewClassName
=
project
.
getProperty
(
"DOKIT_WEBVIEW_CLASS_NAME"
,
""
)
DoKitExtUtil
.
DOKIT_PLUGIN_SWITCH
=
pluginSwitch
DoKitExtUtil
.
DOKIT_LOG_SWITCH
=
logSwitch
DoKitExtUtil
.
SLOW_METHOD_SWITCH
=
slowMethodSwitch
DoKitExtUtil
.
SLOW_METHOD_STRATEGY
=
slowMethodStrategy
DoKitExtUtil
.
STACK_METHOD_LEVEL
=
methodStackLevel
DoKitExtUtil
.
WEBVIEW_CLASS_NAME
=
webviewClassName
"application module ${project.name} is executing..."
.
println
()
...
...
Android/java/doraemonkit/build.gradle
浏览文件 @
d07ceb32
...
...
@@ -66,7 +66,7 @@ dependencies {
implementation
rootProject
.
ext
.
dependencies
[
"recyclerview"
]
implementation
rootProject
.
ext
.
dependencies
[
"kotlin"
]
implementation
rootProject
.
ext
.
dependencies
[
"core-ktx"
]
implementation
rootProject
.
ext
.
dependencies
[
"web
view
"
]
implementation
rootProject
.
ext
.
dependencies
[
"web
kit
"
]
implementation
rootProject
.
ext
.
dependencies
[
"gson"
]
implementation
rootProject
.
ext
.
dependencies
[
"zxing"
]
...
...
@@ -98,6 +98,8 @@ dependencies {
compileOnly
rootProject
.
ext
.
dependencies
[
"picasso"
]
compileOnly
rootProject
.
ext
.
dependencies
[
"fresco"
]
compileOnly
rootProject
.
ext
.
dependencies
[
"image-loader"
]
//腾讯x5
compileOnly
rootProject
.
ext
.
dependencies
[
"tbs"
]
//高德地图定位
compileOnly
rootProject
.
ext
.
dependencies
[
"amap_location"
]
...
...
@@ -105,6 +107,7 @@ dependencies {
compileOnly
rootProject
.
ext
.
dependencies
[
"tencent_location"
]
//百度地图定位
compileOnly
files
(
'libs/BaiduLBS_Android.jar'
)
}
configurations
.
all
{
...
...
Android/java/doraemonkit/src/main/java/com/didichuxing/doraemonkit/aop/WebViewHook.java
浏览文件 @
d07ceb32
...
...
@@ -7,9 +7,9 @@ import android.webkit.WebView;
import
androidx.webkit.WebViewCompat
;
import
com.didichuxing.doraemonkit.constant.DokitConstant
;
import
com.didichuxing.doraemonkit.kit.h5_help.DokitJSI
;
import
com.didichuxing.doraemonkit.kit.h5_help.DokitWebViewClient
;
import
com.didichuxing.doraemonkit.kit.h5_help.DokitX5WebViewClient
;
import
com.didichuxing.doraemonkit.util.LogHelper
;
/**
...
...
@@ -27,21 +27,45 @@ public class WebViewHook {
/**
* webview inject java object
*/
@SuppressLint
({
"AddJavascriptInterface"
,
"RequiresFeature"
,
"SetJavaScriptEnabled"
})
public
static
void
inject
(
WebView
webView
)
{
public
static
void
inject
(
Object
webView
)
{
LogHelper
.
i
(
TAG
,
"====inject===="
);
if
(
webView
!=
null
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
if
(!(
WebViewCompat
.
getWebViewClient
(
webView
)
instanceof
DokitWebViewClient
))
{
WebSettings
settings
=
webView
.
getSettings
();
settings
.
setJavaScriptEnabled
(
true
);
settings
.
setAllowUniversalAccessFromFileURLs
(
true
);
webView
.
addJavascriptInterface
(
new
DokitJSI
(),
"dokitJsi"
);
webView
.
setWebViewClient
(
new
DokitWebViewClient
(
WebViewCompat
.
getWebViewClient
(
webView
)));
}
if
(
webView
instanceof
WebView
)
{
injectNormal
((
WebView
)
webView
);
}
else
if
(
webView
instanceof
com
.
tencent
.
smtt
.
sdk
.
WebView
)
{
injectX5
((
com
.
tencent
.
smtt
.
sdk
.
WebView
)
webView
);
}
}
}
@SuppressLint
({
"AddJavascriptInterface"
,
"RequiresFeature"
,
"SetJavaScriptEnabled"
})
private
static
void
injectNormal
(
WebView
webView
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
if
(!(
WebViewCompat
.
getWebViewClient
(
webView
)
instanceof
DokitWebViewClient
))
{
WebSettings
settings
=
webView
.
getSettings
();
settings
.
setJavaScriptEnabled
(
true
);
settings
.
setAllowUniversalAccessFromFileURLs
(
true
);
webView
.
addJavascriptInterface
(
new
DokitJSI
(),
"dokitJsi"
);
webView
.
setWebViewClient
(
new
DokitWebViewClient
(
WebViewCompat
.
getWebViewClient
(
webView
)));
}
}
}
@SuppressLint
(
"SetJavaScriptEnabled"
)
private
static
void
injectX5
(
com
.
tencent
.
smtt
.
sdk
.
WebView
webView
)
{
LogHelper
.
i
(
TAG
,
"====injectX5===="
);
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
if
(!(
webView
.
getWebViewClient
()
instanceof
DokitX5WebViewClient
))
{
com
.
tencent
.
smtt
.
sdk
.
WebSettings
settings
=
webView
.
getSettings
();
settings
.
setJavaScriptEnabled
(
true
);
settings
.
setAllowUniversalAccessFromFileURLs
(
true
);
webView
.
addJavascriptInterface
(
new
DokitJSI
(),
"dokitJsi"
);
webView
.
setWebViewClient
(
new
DokitX5WebViewClient
(
webView
.
getWebViewClient
()));
}
}
}
}
Android/java/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/DokitWebViewClient.kt
浏览文件 @
d07ceb32
...
...
@@ -68,8 +68,8 @@ class DokitWebViewClient(webViewClient: WebViewClient?) : WebViewClient() {
view
:
WebView
?,
request
:
WebResourceRequest
?
):
WebResourceResponse
?
{
//
是否允许js抓包和数据mock
if
(!
DokitConstant
.
H5_JS_INJECT
)
{
//
开关均被关闭则不进行拦截
if
(!
DokitConstant
.
H5_JS_INJECT
&&
!
DokitConstant
.
H5_VCONSOLE_INJECT
)
{
return
super
.
shouldInterceptRequest
(
view
,
request
)
}
request
?.
let
{
webRequest
->
...
...
@@ -88,8 +88,13 @@ class DokitWebViewClient(webViewClient: WebViewClient?) : WebViewClient() {
}
val
response
=
DokitOkGo
.
get
<
String
>(
url
).
execute
()
//注入本地网络拦截js
var
newHtml
=
injectJsHook
(
response
.
body
()
?.
string
())
var
newHtml
=
if
(
DokitConstant
.
H5_JS_INJECT
)
{
injectJsHook
(
response
.
body
()
?.
string
())
}
else
{
response
.
body
()
?.
string
()
}
//注入vConsole的代码
if
(
DokitConstant
.
H5_VCONSOLE_INJECT
)
{
newHtml
=
injectVConsoleHook
(
newHtml
)
...
...
@@ -187,7 +192,7 @@ class DokitWebViewClient(webViewClient: WebViewClient?) : WebViewClient() {
//是否命中拦截规则
if
(!
interceptMatchedId
.
isNullOrBlank
())
{
JsHookDataManager
.
jsRequestMap
.
remove
(
requestBean
.
requestId
)
return
JsHttpUtil
.
matchedInterceptRule
(
return
JsHttpUtil
.
matched
Normal
InterceptRule
(
httpUrl
,
path
,
interceptMatchedId
,
...
...
Android/java/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/DokitX5WebViewClient.kt
0 → 100644
浏览文件 @
d07ceb32
package
com.didichuxing.doraemonkit.kit.h5_help
import
android.app.Activity
import
android.graphics.Bitmap
import
android.os.Build
import
android.os.Message
import
android.view.KeyEvent
import
androidx.annotation.RequiresApi
import
com.blankj.utilcode.util.ConvertUtils
import
com.blankj.utilcode.util.ResourceUtils
import
com.didichuxing.doraemonkit.constant.DokitConstant
import
com.didichuxing.doraemonkit.kit.core.AbsDokitView
import
com.didichuxing.doraemonkit.kit.core.DokitViewManager
import
com.didichuxing.doraemonkit.kit.h5_help.bean.JsRequestBean
import
com.didichuxing.doraemonkit.kit.network.NetworkManager
import
com.didichuxing.doraemonkit.kit.network.room_db.DokitDbManager
import
com.didichuxing.doraemonkit.okgo.DokitOkGo
import
com.didichuxing.doraemonkit.util.LogHelper
import
com.tencent.smtt.export.external.interfaces.*
import
com.tencent.smtt.sdk.MimeTypeMap
import
com.tencent.smtt.sdk.WebView
import
com.tencent.smtt.sdk.WebViewClient
import
okhttp3.*
import
org.jsoup.Jsoup
import
java.net.URLDecoder
/**
* ================================================
* 作 者:jint(金台)
* 版 本:1.0
* 创建日期:2020/8/28-17:22
* 描 述:切面dokit
* 修订历史:
* ================================================
*/
class
DokitX5WebViewClient
(
webViewClient
:
WebViewClient
?)
:
WebViewClient
()
{
private
val
TAG
=
"DokitWebViewClient"
private
val
mWebViewClient
:
WebViewClient
?
=
webViewClient
private
val
mOkHttpClient
=
OkHttpClient
()
/**
* 更新悬浮窗上的链接
*/
private
fun
updateH5DokitUrl
(
view
:
WebView
?,
url
:
String
?)
{
view
?.
let
{
it
->
if
(
it
.
context
is
Activity
)
{
val
activity
=
it
.
context
as
Activity
val
absDokitView
:
AbsDokitView
?
=
DokitViewManager
.
getInstance
()
.
getDokitView
(
activity
,
H5DokitView
::
class
.
java
.
simpleName
)
absDokitView
?.
let
{
h5DokitView
->
(
h5DokitView
as
H5DokitView
).
updateUrl
(
url
)
}
}
}
}
override
fun
shouldOverrideUrlLoading
(
view
:
WebView
?,
url
:
String
):
Boolean
{
updateH5DokitUrl
(
view
,
url
)
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
shouldOverrideUrlLoading
(
view
,
url
)
}
return
super
.
shouldOverrideUrlLoading
(
view
,
url
)
}
@RequiresApi
(
Build
.
VERSION_CODES
.
LOLLIPOP
)
override
fun
shouldInterceptRequest
(
view
:
WebView
?,
request
:
WebResourceRequest
?
):
WebResourceResponse
?
{
//开关均被关闭则不进行拦截
if
(!
DokitConstant
.
H5_JS_INJECT
&&
!
DokitConstant
.
H5_VCONSOLE_INJECT
)
{
return
super
.
shouldInterceptRequest
(
view
,
request
)
}
request
?.
let
{
webRequest
->
//加载页面资源
if
(
webRequest
.
isForMainFrame
)
{
LogHelper
.
i
(
TAG
,
"url===>${webRequest.url?.toString()} method==>${webRequest.method} thread==>${Thread.currentThread().name}"
)
val
httpUrl
=
HttpUrl
.
parse
(
webRequest
.
url
?.
toString
())
val
url
=
if
(
httpUrl
?.
url
()
?.
query
.
isNullOrBlank
())
{
webRequest
.
url
?.
toString
()
+
"?dokit_flag=web"
}
else
{
webRequest
.
url
?.
toString
()
+
"&dokit_flag=web"
}
val
response
=
DokitOkGo
.
get
<
String
>(
url
).
execute
()
//注入本地网络拦截js
var
newHtml
=
if
(
DokitConstant
.
H5_JS_INJECT
)
{
injectJsHook
(
response
.
body
()
?.
string
())
}
else
{
response
.
body
()
?.
string
()
}
//注入vConsole的代码
if
(
DokitConstant
.
H5_VCONSOLE_INJECT
)
{
newHtml
=
injectVConsoleHook
(
newHtml
)
}
return
WebResourceResponse
(
"text/html"
,
response
.
header
(
"content-encoding"
,
"utf-8"
),
ConvertUtils
.
string2InputStream
(
newHtml
,
"utf-8"
)
)
}
else
{
//加载js网络请求
if
(
webRequest
.
url
.
toString
().
contains
(
"dokit_flag"
))
{
val
jsRequestId
=
getUrlQuery
(
webRequest
.
url
.
toString
(),
"dokit_flag"
)
val
jsRequestBean
=
JsHookDataManager
.
jsRequestMap
[
jsRequestId
]
LogHelper
.
i
(
TAG
,
jsRequestBean
.
toString
())
jsRequestBean
?.
let
{
requestBean
->
val
url
=
HttpUrl
.
parse
(
requestBean
.
url
)
val
host
=
url
?.
host
()
//如果是dokit mock host 则不进行拦截
if
(
host
.
equals
(
NetworkManager
.
MOCK_HOST
,
true
))
{
JsHookDataManager
.
jsRequestMap
.
remove
(
requestBean
.
requestId
)
return
null
}
//web 抓包
if
(
NetworkManager
.
isActive
())
{
try
{
//构建okhttp用来抓包
val
newRequest
:
Request
=
JsHttpUtil
.
createOkHttpRequest
(
requestBean
)
if
(!
JsHttpUtil
.
matchWhiteHost
(
newRequest
))
{
//发送模拟请求
mOkHttpClient
.
newCall
(
newRequest
).
execute
()
}
}
catch
(
e
:
Exception
)
{
e
.
printStackTrace
()
}
}
// web 数据mock
return
dealMock
(
requestBean
,
url
)
}
}
else
{
return
super
.
shouldInterceptRequest
(
view
,
request
)
}
}
}
return
super
.
shouldInterceptRequest
(
view
,
request
)
}
/**
* 处理数据mock的相关逻辑
*/
private
fun
dealMock
(
requestBean
:
JsRequestBean
,
url
:
HttpUrl
?
):
WebResourceResponse
?
{
url
?.
let
{
httpUrl
->
try
{
val
path
=
URLDecoder
.
decode
(
httpUrl
.
encodedPath
(),
"utf-8"
)
val
queries
=
httpUrl
.
query
()
val
jsonQuery
=
JsHttpUtil
.
transformQuery
(
queries
)
val
jsonRequestBody
=
JsHttpUtil
.
transformRequestBody
(
requestBean
.
method
,
requestBean
.
body
,
requestBean
.
headers
)
val
interceptMatchedId
=
DokitDbManager
.
getInstance
().
isMockMatched
(
path
,
jsonQuery
,
jsonRequestBody
,
DokitDbManager
.
MOCK_API_INTERCEPT
,
DokitDbManager
.
FROM_SDK_OTHER
)
val
templateMatchedId
=
DokitDbManager
.
getInstance
().
isMockMatched
(
path
,
jsonQuery
,
jsonRequestBody
,
DokitDbManager
.
MOCK_API_TEMPLATE
,
DokitDbManager
.
FROM_SDK_OTHER
)
val
newRequest
:
Request
=
JsHttpUtil
.
createOkHttpRequest
(
requestBean
)
//发送模拟请求
val
newResponse
=
mOkHttpClient
.
newCall
(
newRequest
).
execute
()
//是否命中拦截规则
if
(!
interceptMatchedId
.
isNullOrBlank
())
{
JsHookDataManager
.
jsRequestMap
.
remove
(
requestBean
.
requestId
)
return
JsHttpUtil
.
matchedX5InterceptRule
(
httpUrl
,
path
,
interceptMatchedId
,
templateMatchedId
,
newRequest
,
newResponse
,
mOkHttpClient
)
}
//是否命中模板规则
if
(!
templateMatchedId
.
isNullOrBlank
())
{
JsHttpUtil
.
matchedTemplateRule
(
newResponse
,
path
,
templateMatchedId
)
}
}
catch
(
e
:
Exception
)
{
e
.
printStackTrace
()
}
}
JsHookDataManager
.
jsRequestMap
.
remove
(
requestBean
.
requestId
)
return
null
}
private
fun
getUrlQuery
(
url
:
String
,
key
:
String
):
String
?
{
val
httpUrl
=
HttpUrl
.
parse
(
url
)
val
queries
=
httpUrl
?.
url
()
?.
query
?.
split
(
"&"
)
val
queryMap
=
mutableMapOf
<
String
,
String
>()
queries
?.
forEach
{
val
keyAndValue
=
it
.
split
(
"="
)
queryMap
[
keyAndValue
[
0
]]
=
keyAndValue
[
1
]
}
return
queryMap
[
key
]
}
/**
* 注入hook js 哇共诺请求的代码
*/
private
fun
injectJsHook
(
html
:
String
?):
String
{
//读取本地js hook 代码
val
jsHook
=
ResourceUtils
.
readAssets2String
(
"dokit_js_hook.html"
)
val
doc
=
Jsoup
.
parse
(
html
)
doc
.
outputSettings
().
prettyPrint
(
true
)
val
elements
=
doc
.
getElementsByTag
(
"head"
)
if
(
elements
.
size
>
0
)
{
elements
[
0
].
prepend
(
jsHook
)
}
return
doc
.
toString
()
}
/**
* 注入 vConsole的代码
*/
private
fun
injectVConsoleHook
(
html
:
String
?):
String
{
//读取本地js hook 代码
val
vconsoleHook
=
ResourceUtils
.
readAssets2String
(
"dokit_js_vconsole_hook.html"
)
val
doc
=
Jsoup
.
parse
(
html
)
doc
.
outputSettings
().
prettyPrint
(
true
)
val
elements
=
doc
.
getElementsByTag
(
"head"
)
if
(
elements
.
size
>
0
)
{
elements
[
elements
.
size
-
1
].
append
(
vconsoleHook
)
}
return
doc
.
toString
()
}
//get mime type by url
private
fun
getMimeType
(
url
:
String
):
String
?
{
var
type
:
String
?
=
null
val
extension
=
MimeTypeMap
.
getFileExtensionFromUrl
(
url
)
if
(
extension
!=
null
)
{
when
(
extension
)
{
"js"
->
type
=
"text/javascript"
"woff"
->
type
=
"application/font-woff"
"woff2"
->
type
=
"application/font-woff2"
"ttf"
->
type
=
"application/x-font-ttf"
"eot"
->
type
=
"application/vnd.ms-fontobject"
"svg"
->
type
=
"text/javascript"
else
->
type
=
MimeTypeMap
.
getSingleton
().
getMimeTypeFromExtension
(
extension
)
}
}
return
type
}
@RequiresApi
(
Build
.
VERSION_CODES
.
N
)
override
fun
shouldOverrideUrlLoading
(
view
:
WebView
?,
request
:
WebResourceRequest
?):
Boolean
{
updateH5DokitUrl
(
view
,
request
?.
url
?.
path
)
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
shouldOverrideUrlLoading
(
view
,
request
)
}
return
super
.
shouldOverrideUrlLoading
(
view
,
request
)
}
override
fun
shouldInterceptRequest
(
view
:
WebView
?,
url
:
String
?):
WebResourceResponse
?
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
shouldInterceptRequest
(
view
,
url
)
}
return
super
.
shouldInterceptRequest
(
view
,
url
)
}
override
fun
onPageStarted
(
view
:
WebView
?,
url
:
String
?,
favicon
:
Bitmap
?)
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
onPageStarted
(
view
,
url
,
favicon
)
}
super
.
onPageStarted
(
view
,
url
,
favicon
)
}
override
fun
onPageFinished
(
view
:
WebView
?,
url
:
String
?)
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
onPageFinished
(
view
,
url
)
}
super
.
onPageFinished
(
view
,
url
)
}
override
fun
onLoadResource
(
view
:
WebView
?,
url
:
String
?)
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
onLoadResource
(
view
,
url
)
}
super
.
onLoadResource
(
view
,
url
)
}
@RequiresApi
(
Build
.
VERSION_CODES
.
M
)
override
fun
onPageCommitVisible
(
view
:
WebView
?,
url
:
String
?)
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
onPageCommitVisible
(
view
,
url
)
}
super
.
onPageCommitVisible
(
view
,
url
)
}
override
fun
onTooManyRedirects
(
view
:
WebView
?,
cancelMsg
:
Message
?,
continueMsg
:
Message
?)
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
onTooManyRedirects
(
view
,
cancelMsg
,
continueMsg
)
}
super
.
onTooManyRedirects
(
view
,
cancelMsg
,
continueMsg
)
}
override
fun
onReceivedError
(
view
:
WebView
?,
errorCode
:
Int
,
description
:
String
?,
failingUrl
:
String
?
)
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
onReceivedError
(
view
,
errorCode
,
description
,
failingUrl
)
}
super
.
onReceivedError
(
view
,
errorCode
,
description
,
failingUrl
)
}
@RequiresApi
(
Build
.
VERSION_CODES
.
M
)
override
fun
onReceivedError
(
view
:
WebView
?,
request
:
WebResourceRequest
?,
error
:
WebResourceError
?
)
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
onReceivedError
(
view
,
request
,
error
)
}
super
.
onReceivedError
(
view
,
request
,
error
)
}
@RequiresApi
(
Build
.
VERSION_CODES
.
M
)
override
fun
onReceivedHttpError
(
view
:
WebView
?,
request
:
WebResourceRequest
?,
errorResponse
:
WebResourceResponse
?
)
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
onReceivedHttpError
(
view
,
request
,
errorResponse
)
}
super
.
onReceivedHttpError
(
view
,
request
,
errorResponse
)
}
override
fun
onFormResubmission
(
view
:
WebView
?,
dontResend
:
Message
?,
resend
:
Message
?)
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
onFormResubmission
(
view
,
dontResend
,
resend
)
}
super
.
onFormResubmission
(
view
,
dontResend
,
resend
)
}
override
fun
doUpdateVisitedHistory
(
view
:
WebView
?,
url
:
String
?,
isReload
:
Boolean
)
{
updateH5DokitUrl
(
view
,
url
)
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
doUpdateVisitedHistory
(
view
,
url
,
isReload
)
}
super
.
doUpdateVisitedHistory
(
view
,
url
,
isReload
)
}
@RequiresApi
(
Build
.
VERSION_CODES
.
LOLLIPOP
)
override
fun
onReceivedClientCertRequest
(
view
:
WebView
?,
request
:
ClientCertRequest
?)
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
onReceivedClientCertRequest
(
view
,
request
)
}
super
.
onReceivedClientCertRequest
(
view
,
request
)
}
override
fun
onReceivedHttpAuthRequest
(
view
:
WebView
?,
handler
:
HttpAuthHandler
?,
host
:
String
?,
realm
:
String
?
)
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
onReceivedHttpAuthRequest
(
view
,
handler
,
host
,
realm
)
}
super
.
onReceivedHttpAuthRequest
(
view
,
handler
,
host
,
realm
)
}
override
fun
shouldOverrideKeyEvent
(
view
:
WebView
?,
event
:
KeyEvent
?):
Boolean
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
shouldOverrideKeyEvent
(
view
,
event
)
}
return
super
.
shouldOverrideKeyEvent
(
view
,
event
)
}
override
fun
onUnhandledKeyEvent
(
view
:
WebView
?,
event
:
KeyEvent
?)
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
onUnhandledKeyEvent
(
view
,
event
)
}
super
.
onUnhandledKeyEvent
(
view
,
event
)
}
override
fun
onScaleChanged
(
view
:
WebView
?,
oldScale
:
Float
,
newScale
:
Float
)
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
onScaleChanged
(
view
,
oldScale
,
newScale
)
}
super
.
onScaleChanged
(
view
,
oldScale
,
newScale
)
}
override
fun
onReceivedLoginRequest
(
view
:
WebView
?,
realm
:
String
?,
account
:
String
?,
args
:
String
?
)
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
onReceivedLoginRequest
(
view
,
realm
,
account
,
args
)
}
super
.
onReceivedLoginRequest
(
view
,
realm
,
account
,
args
)
}
override
fun
onReceivedSslError
(
p0
:
WebView
?,
p1
:
SslErrorHandler
?,
p2
:
com
.
tencent
.
smtt
.
export
.
external
.
interfaces
.
SslError
?
)
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
onReceivedSslError
(
p0
,
p1
,
p2
)
}
super
.
onReceivedSslError
(
p0
,
p1
,
p2
)
}
override
fun
onDetectedBlankScreen
(
p0
:
String
?,
p1
:
Int
)
{
if
(
mWebViewClient
!=
null
)
{
return
mWebViewClient
.
onDetectedBlankScreen
(
p0
,
p1
)
}
super
.
onDetectedBlankScreen
(
p0
,
p1
)
}
}
\ No newline at end of file
Android/java/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/H5DokitView.kt
浏览文件 @
d07ceb32
...
...
@@ -47,6 +47,7 @@ class H5DokitView : AbsDokitView() {
private
lateinit
var
mRvLocal
:
RecyclerView
private
lateinit
var
mRvSession
:
RecyclerView
private
lateinit
var
mRvWrap
:
LinearLayout
private
lateinit
var
mMoreWrap
:
RelativeLayout
private
lateinit
var
mHolder
:
TextView
private
lateinit
var
mLocalAdapter
:
LocalStorageAdapter
private
lateinit
var
mSessionAdapter
:
LocalStorageAdapter
...
...
@@ -103,6 +104,7 @@ class H5DokitView : AbsDokitView() {
}
mRvWrap
=
it
.
findViewById
(
R
.
id
.
ll_rv_wrap
)
mMoreWrap
=
it
.
findViewById
(
R
.
id
.
rl_more_wrap
)
mHolder
=
it
.
findViewById
(
R
.
id
.
tv_holder
)
mHolder
.
text
=
"更多"
mHolder
.
setOnClickListener
{
...
...
@@ -156,8 +158,10 @@ class H5DokitView : AbsDokitView() {
val
webView
=
performTraverseView
()
if
(
webView
==
null
)
{
mTvLink
.
text
=
"当前页面不存在WebView"
mMoreWrap
.
visibility
=
View
.
GONE
}
else
{
mTvLink
.
text
=
webView
.
url
mMoreWrap
.
visibility
=
View
.
VISIBLE
}
mJsCheckBox
.
isChecked
=
DokitConstant
.
H5_JS_INJECT
invalidate
()
...
...
@@ -215,7 +219,7 @@ class H5DokitView : AbsDokitView() {
normalLayoutParams
?.
let
{
it
.
width
=
ConvertUtils
.
dp2px
(
300.0f
)
if
(
isOpen
)
{
it
.
height
=
ConvertUtils
.
dp2px
(
6
0
0.0f
)
it
.
height
=
ConvertUtils
.
dp2px
(
6
5
0.0f
)
}
else
{
it
.
height
=
DokitViewLayoutParams
.
WRAP_CONTENT
}
...
...
Android/java/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/JsHttpUtil.kt
浏览文件 @
d07ceb32
...
...
@@ -104,7 +104,7 @@ internal object JsHttpUtil {
/**
* 返回null 即代表返回原来的数据
*/
fun
matchedInterceptRule
(
fun
matched
Normal
InterceptRule
(
url
:
HttpUrl
,
path
:
String
,
interceptMatchedId
:
String
,
...
...
@@ -168,7 +168,7 @@ internal object JsHttpUtil {
//判断新的response是否有数据
return
if
(
newResponse
.
body
()
!=
null
)
{
matchedTemplateRule
(
newResponse
,
path
,
templateMatchedId
)
createWebResourceResponse
(
newResponse
)
create
Normal
WebResourceResponse
(
newResponse
)
}
else
{
matchedTemplateRule
(
oldResponse
,
path
,
templateMatchedId
)
null
...
...
@@ -178,7 +178,7 @@ internal object JsHttpUtil {
return
null
}
private
fun
createWebResourceResponse
(
response
:
Response
):
WebResourceResponse
{
private
fun
create
Normal
WebResourceResponse
(
response
:
Response
):
WebResourceResponse
{
return
WebResourceResponse
(
response
.
body
()
?.
contentType
().
toString
(),
"UTF-8"
,
...
...
@@ -186,6 +186,91 @@ internal object JsHttpUtil {
)
}
/**
* 返回null 即代表返回原来的数据
*/
fun
matchedX5InterceptRule
(
url
:
HttpUrl
,
path
:
String
,
interceptMatchedId
:
String
,
templateMatchedId
:
String
,
oldRequest
:
Request
,
oldResponse
:
Response
,
okHttpClient
:
OkHttpClient
):
com
.
tencent
.
smtt
.
export
.
external
.
interfaces
.
WebResourceResponse
?
{
//判断是否需要重定向数据接口
//http https
//判断是否需要重定向数据接口
//http https
val
scheme
=
url
.
scheme
()
val
interceptApiBean
=
DokitDbManager
.
getInstance
().
getInterceptApiByIdInMap
(
path
,
interceptMatchedId
,
DokitDbManager
.
FROM_SDK_OTHER
)
if
(
interceptApiBean
==
null
)
{
matchedTemplateRule
(
oldResponse
,
path
,
templateMatchedId
)
return
null
}
interceptApiBean
as
MockInterceptApiBean
val
selectedSceneId
=
interceptApiBean
.
selectedSceneId
//开关是否被打开
//开关是否被打开
if
(!
interceptApiBean
.
isOpen
)
{
matchedTemplateRule
(
oldResponse
,
path
,
templateMatchedId
)
return
null
}
//判断是否有选中的场景
//判断是否有选中的场景
if
(
TextUtils
.
isEmpty
(
selectedSceneId
))
{
matchedTemplateRule
(
oldResponse
,
path
,
templateMatchedId
)
return
null
}
val
sb
=
StringBuilder
()
val
newUrl
:
String
newUrl
=
if
(
NetworkManager
.
MOCK_SCHEME_HTTP
.
contains
(
scheme
.
toLowerCase
()))
{
sb
.
append
(
NetworkManager
.
MOCK_SCHEME_HTTP
).
append
(
NetworkManager
.
MOCK_HOST
)
.
append
(
"/api/app/scene/"
).
append
(
selectedSceneId
).
toString
()
}
else
{
sb
.
append
(
NetworkManager
.
MOCK_SCHEME_HTTPS
).
append
(
NetworkManager
.
MOCK_HOST
)
.
append
(
"/api/app/scene/"
).
append
(
selectedSceneId
).
toString
()
}
val
newRequest
=
Request
.
Builder
()
.
method
(
"GET"
,
null
)
.
url
(
newUrl
).
build
()
//需要提前关闭数据流 不然在某些场景下会报错
oldResponse
.
close
()
val
newResponse
:
Response
=
okHttpClient
.
newCall
(
newRequest
).
execute
()
if
(
newResponse
.
code
()
==
200
)
{
//拦截命中提示
ToastUtils
.
showShort
(
"接口别名:=="
+
interceptApiBean
.
mockApiName
+
"==已被拦截"
)
//判断新的response是否有数据
return
if
(
newResponse
.
body
()
!=
null
)
{
matchedTemplateRule
(
newResponse
,
path
,
templateMatchedId
)
createX5WebResourceResponse
(
newResponse
)
}
else
{
matchedTemplateRule
(
oldResponse
,
path
,
templateMatchedId
)
null
}
}
matchedTemplateRule
(
oldResponse
,
path
,
templateMatchedId
)
return
null
}
private
fun
createX5WebResourceResponse
(
response
:
Response
):
com
.
tencent
.
smtt
.
export
.
external
.
interfaces
.
WebResourceResponse
{
return
com
.
tencent
.
smtt
.
export
.
external
.
interfaces
.
WebResourceResponse
(
response
.
body
()
?.
contentType
().
toString
(),
"UTF-8"
,
ConvertUtils
.
string2InputStream
(
response
.
bodyContent
(),
"UTF-8"
)
)
}
/**
*是否命中模板功能
...
...
Android/java/doraemonkit/src/main/res/layout/dk_float_h5_info.xml
浏览文件 @
d07ceb32
...
...
@@ -56,6 +56,14 @@
</LinearLayout>
<View
style=
"@style/DK.Divider"
/>
<TextView
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:text=
"tips:js hook和vConsole的代码均在页面加载时注入,状态改变时需要重新加载页面才能生效"
android:textColor=
"@color/dk_color_FF0006"
android:textSize=
"10sp"
/>
<!-- js hook switch-->
<RelativeLayout
android:id=
"@+id/rl_js_switch"
...
...
@@ -109,6 +117,7 @@
<View
style=
"@style/DK.Divider"
/>
<RelativeLayout
android:id=
"@+id/rl_more_wrap"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"10dp"
>
...
...
Android/java/gradle.properties
浏览文件 @
d07ceb32
...
...
@@ -16,14 +16,14 @@ android.debug.obsoleteApi=true
android.useAndroidX
=
true
android.enableJetifier
=
true
android.injected.testOnly
=
false
kotlin.code.style
=
official
#dokit全局配置
# 插件开关
DOKIT_PLUGIN_SWITCH
=
true
# 插件日志
DOKIT_LOG_SWITCH
=
true
# webview 的全限定名
DOKIT_WEBVIEW_CLASS_NAME
=
com/didichuxing/doraemonkit/widget/webview/MyWebView
#dokit 慢函数开关
DOKIT_METHOD_SWITCH
=
true
#dokit 函数调用栈层级
...
...
@@ -31,3 +31,4 @@ DOKIT_METHOD_STACK_LEVEL=4
#0:默认模式 打印函数调用栈 需添加指定入口 默认为application onCreate 和attachBaseContext
#1:普通模式 运行时打印某个函数的耗时 全局业务代码函数插入
DOKIT_METHOD_STRATEGY
=
0
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录