提交 8a3fede7 编写于 作者: J jackjintai

android:优化H5 helper

上级 add889e9
......@@ -123,7 +123,7 @@ dependencies {
implementation rootProject.ext.dependencies["retrofit2"]
implementation rootProject.ext.dependencies["retrofit2_rxjava2"]
implementation rootProject.ext.dependencies["retrofit2_gson"]
implementation rootProject.ext.dependencies["okhttp_v4"]
implementation rootProject.ext.dependencies["okhttp_v3"]
implementation rootProject.ext.dependencies["okgo"]
implementation rootProject.ext.dependencies["glide"]
// implementation rootProject.ext.dependencies["glide_okhttp3"]
......
......@@ -17,7 +17,7 @@
android:theme="@style/AppTheme"
tools:replace="android:allowBackup">
<activity android:name=".MainDebugActivityOkhttpV4">
<activity android:name=".MainDebugActivityOkhttpV3">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
......
......@@ -3,6 +3,7 @@ package com.didichuxing.doraemondemo
import android.annotation.SuppressLint
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.webkit.*
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
......@@ -13,7 +14,7 @@ import androidx.appcompat.app.AppCompatActivity
class WebViewNormalActivity : AppCompatActivity() {
val TAG = "WebViewActivity"
lateinit var mWebView: WebView
// val url = "file:///android_asset/dokit_index.html"
val url = "https://m.v.qq.com/index.html"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
......@@ -22,9 +23,9 @@ class WebViewNormalActivity : AppCompatActivity() {
initWebView(mWebView)
// webView.loadUrl("https://page-daily.kuaidadi.com/m/ddPage_0sTyVhyq.html")
// WebViewHook.inject(webView)
//webView.loadUrl(url)
mWebView.loadUrl(url)
// webView.loadUrl("file:///android_asset/dokit_index.html")
mWebView.loadUrl("https://www.dokit.cn")
//mWebView.loadUrl("https://www.dokit.cn")
// webView.loadUrl("http://xingyun.xiaojukeji.com/docs/dokit/#/intro")
}
......@@ -79,7 +80,19 @@ class WebViewNormalActivity : AppCompatActivity() {
webView.webChromeClient = object : WebChromeClient() {
override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean {
//LogHelper.i(TAG, "consoleMessage===>${consoleMessage?.message()}")
val message = consoleMessage!!.message()
val lineNumber = consoleMessage.lineNumber()
val sourceID = consoleMessage.sourceId()
val messageLevel = consoleMessage.message()
Log.i(
TAG, String.format(
"[%s] sourceID: %s lineNumber: %n message: %s",
messageLevel, sourceID, lineNumber, message
)
)
//Log.i(TAG, "consoleMessage===>${consoleMessage?.message()}")
return super.onConsoleMessage(consoleMessage)
}
}
......
......@@ -19,7 +19,7 @@ import com.tencent.smtt.sdk.WebViewClient
class WebViewX5Activity : AppCompatActivity() {
val TAG = "WebViewActivity"
lateinit var mWebView: WebView
// val url = "file:///android_asset/dokit_index.html"
val url = "https://m.v.qq.com/index.html"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
......@@ -28,9 +28,9 @@ class WebViewX5Activity : AppCompatActivity() {
initWebView(mWebView)
// webView.loadUrl("https://page-daily.kuaidadi.com/m/ddPage_0sTyVhyq.html")
// WebViewHook.inject(webView)
//webView.loadUrl(url)
mWebView.loadUrl(url)
// webView.loadUrl("file:///android_asset/dokit_index.html")
mWebView.loadUrl("https://www.dokit.cn")
//mWebView.loadUrl("https://www.dokit.cn")
// webView.loadUrl("http://xingyun.xiaojukeji.com/docs/dokit/#/intro")
}
......
......@@ -43,5 +43,6 @@ dependencies {
//compileOnly rootProject.ext.dependencies["okio"]
implementation project(":doraemonkit-okhttp-v3")
implementation project(":doraemonkit-okhttp-v4")
compileOnly rootProject.ext.dependencies["utilcode"]
}
\ No newline at end of file
package com.didichuxing.doraemonkit.okhttp_api
import android.util.Log
import com.blankj.utilcode.util.ReflectUtils
import okhttp3.*
import okio.BufferedSink
import okio.Sink
......@@ -15,8 +17,56 @@ import java.net.URL
* ================================================
*/
object OkHttpWrap {
val okHttpVersion: String by lazy {
var version = ""
try {
version =
ReflectUtils.reflect("okhttp3.internal.Version").method("userAgent").get<String>()
} catch (e: Exception) {
}
try {
if (version.isEmpty()) {
version = ReflectUtils.reflect("okhttp3.internal.Version").field("userAgent")
.get<String>()
}
} catch (e: Exception) {
}
try {
if (version.isEmpty()) {
version = ReflectUtils.reflect("okhttp3.OkHttp").field("VERSION").get<String>()
}
} catch (e: Exception) {
}
if (version.isNotEmpty()) {
val split = version.split("/")
if (split.size >= 2) {
version = split[split.size - 1]
}
}
Log.v("OkHttpWrap", "version===>$version")
version
}
private val isV4: Boolean by lazy {
if (okHttpVersion.startsWith("4.")) {
Log.v("OkHttpWrap", "isV4===>true")
return@lazy true
} else if (okHttpVersion.startsWith("3.")) {
Log.v("OkHttpWrap", "isV4===>false")
return@lazy false
}
return@lazy false
}
fun createHttpUrl(url: String?): HttpUrl? {
return if (isV4()) {
return if (isV4) {
OkHttpWrapV4.createHttpUrl(url)
} else {
OkHttpWrapV3.createHttpUrl(url)
......@@ -26,7 +76,7 @@ object OkHttpWrap {
fun toUrl(httpUrl: HttpUrl?): URL? {
return if (isV4()) {
return if (isV4) {
OkHttpWrapV4.toUrl(httpUrl)
} else {
OkHttpWrapV3.toUrl(httpUrl)
......@@ -34,7 +84,7 @@ object OkHttpWrap {
}
fun toResponseBody(response: Response?): ResponseBody? {
return if (isV4()) {
return if (isV4) {
OkHttpWrapV4.toResponseBody(response)
} else {
OkHttpWrapV3.toResponseBody(response)
......@@ -43,7 +93,7 @@ object OkHttpWrap {
fun toHttpQuery(httpUrl: HttpUrl?): String? {
return if (isV4()) {
return if (isV4) {
OkHttpWrapV4.toHttpQuery(httpUrl)
} else {
OkHttpWrapV3.toHttpQuery(httpUrl)
......@@ -52,7 +102,7 @@ object OkHttpWrap {
fun toEncodedPath(httpUrl: HttpUrl?): String? {
return if (isV4()) {
return if (isV4) {
OkHttpWrapV4.toEncodedPath(httpUrl)
} else {
OkHttpWrapV3.toEncodedPath(httpUrl)
......@@ -61,7 +111,7 @@ object OkHttpWrap {
fun toRequestHost(httpUrl: HttpUrl?): String? {
return if (isV4()) {
return if (isV4) {
OkHttpWrapV4.toRequestHost(httpUrl)
} else {
OkHttpWrapV3.toRequestHost(httpUrl)
......@@ -69,7 +119,7 @@ object OkHttpWrap {
}
fun toRequestHost(request: Request): String? {
return if (isV4()) {
return if (isV4) {
OkHttpWrapV4.toRequestHost(request)
} else {
OkHttpWrapV3.toRequestHost(request)
......@@ -77,7 +127,7 @@ object OkHttpWrap {
}
fun toResponseHost(response: Response): String? {
return if (isV4()) {
return if (isV4) {
OkHttpWrapV4.toResponseHost(response)
} else {
OkHttpWrapV3.toResponseHost(response)
......@@ -86,7 +136,7 @@ object OkHttpWrap {
fun toScheme(httpUrl: HttpUrl): String {
return if (isV4()) {
return if (isV4) {
OkHttpWrapV4.toScheme(httpUrl)
} else {
OkHttpWrapV3.toScheme(httpUrl)
......@@ -95,7 +145,7 @@ object OkHttpWrap {
fun toResponseCode(response: Response): Int {
return if (isV4()) {
return if (isV4) {
OkHttpWrapV4.toResponseCode(response)
} else {
OkHttpWrapV3.toResponseCode(response)
......@@ -104,7 +154,7 @@ object OkHttpWrap {
fun toMediaType(contentType: String?): MediaType? {
return if (isV4()) {
return if (isV4) {
OkHttpWrapV4.toMediaType(contentType)
} else {
OkHttpWrapV3.toMediaType(contentType)
......@@ -112,40 +162,20 @@ object OkHttpWrap {
}
fun toRequestBody(content: String?, mediaType: MediaType?): RequestBody? {
return if (isV4()) {
return if (isV4) {
OkHttpWrapV4.toRequestBody(content, mediaType)
} else {
OkHttpWrapV3.toRequestBody(content, mediaType)
}
}
fun getVersion(): String? {
return if (isV4()) {
OkHttpWrapV4.getVersion()
} else {
OkHttpWrapV3.getVersion()
}
}
/**
* 判断okhttp是否是V4版本
*/
fun isV4(): Boolean {
try {
Class.forName("okhttp3.OkHttp")
return true
} catch (e: ClassNotFoundException) {
return false
}
}
fun createByteCountBufferedSink(sink: Sink, byteCount: Long): BufferedSink {
return if (isV4()) {
return if (isV4) {
ByteCountBufferedSinkV4(sink, byteCount)
} else {
ByteCountBufferedSinkV3(sink, byteCount)
}
}
}
\ No newline at end of file
......@@ -71,8 +71,5 @@ object OkHttpWrapV3 {
return RequestBody.create(mediaType, content)
}
fun getVersion(): String? {
val split = Version.userAgent().split("/")
return "V_${split[split.size - 1]}"
}
}
\ No newline at end of file
......@@ -20,6 +20,7 @@ import okio.Timeout;
* 可以设置每次写入大小的BufferedSink
* <p>
* Created by jintai on 2020-10-20 16:07
* 支持4.3.0+ 4.0.0 4.1.0 4.2.0 不支持
*/
public class ByteCountBufferedSinkV4 implements BufferedSink {
......
......@@ -4,6 +4,7 @@ import okhttp3.*
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.internal.userAgent
import java.net.URL
/**
......@@ -69,7 +70,4 @@ object OkHttpWrapV4 {
return content?.toRequestBody(mediaType)
}
fun getVersion(): String? {
return "V_${OkHttp.VERSION}"
}
}
\ No newline at end of file
......@@ -90,5 +90,4 @@
for(var i=0; i<sessionStorage.length;i++){
dokitJsi.sessionStorageSetItem(sessionStorage.key(i),sessionStorage.getItem(sessionStorage.key(i)));
}
</script>
\ No newline at end of file
</script>
\ No newline at end of file
......@@ -47,7 +47,7 @@ public class WebViewHook {
settings.setJavaScriptEnabled(true);
settings.setAllowUniversalAccessFromFileURLs(true);
webView.addJavascriptInterface(new DokitJSI(), "dokitJsi");
webView.setWebViewClient(new DokitWebViewClient(WebViewCompat.getWebViewClient(webView)));
webView.setWebViewClient(new DokitWebViewClient(WebViewCompat.getWebViewClient(webView), settings.getUserAgentString()));
}
}
}
......@@ -63,7 +63,7 @@ public class WebViewHook {
settings.setJavaScriptEnabled(true);
settings.setAllowUniversalAccessFromFileURLs(true);
webView.addJavascriptInterface(new DokitJSI(), "dokitJsi");
webView.setWebViewClient(new DokitX5WebViewClient(webView.getWebViewClient()));
webView.setWebViewClient(new DokitX5WebViewClient(webView.getWebViewClient(), settings.getUserAgentString()));
}
}
}
......
......@@ -1109,7 +1109,12 @@ final class ObsoleteUrlFactory implements URLStreamHandlerFactory, Cloneable {
@Override
public void addRequestProperty(String field, String newValue) {
delegate.addRequestProperty(field, newValue);
try {
delegate.addRequestProperty(field, newValue);
} catch (Exception e) {
}
}
@Override
......
......@@ -42,11 +42,16 @@ public abstract class BaseServiceHooker implements InvocationHandler {
if (mOriginService == null && proxy == null) {
return null;
}
if (getMethodHandlers().containsKey(method.getName()) && getMethodHandlers().get(method.getName()) != null) {
return getMethodHandlers().get(method.getName()).onInvoke(this.mOriginService, proxy, method, args);
} else {
return method.invoke(mOriginService, args);
try {
if (getMethodHandlers().containsKey(method.getName()) && getMethodHandlers().get(method.getName()) != null) {
return getMethodHandlers().get(method.getName()).onInvoke(this.mOriginService, proxy, method, args);
} else {
return method.invoke(mOriginService, args);
}
} catch (Exception e) {
return null;
}
}
@SuppressWarnings("unchecked")
......
......@@ -167,19 +167,26 @@ public class LocationHooker extends BaseServiceHooker {
*/
@Override
public Object onInvoke(Object originService, Object proxy, Method method, Object[] args) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException {
if (!GpsMockManager.getInstance().isMocking()) {
try {
if (!GpsMockManager.getInstance().isMocking()) {
return method.invoke(originService, args);
}
Object listenerTransport = args[1];
//LocationListener mListener 类型
Field mListenerField = listenerTransport.getClass().getDeclaredField("mListener");
mListenerField.setAccessible(true);
LocationListener locationListener = (LocationListener) mListenerField.get(listenerTransport);
LocationListenerProxy locationListenerProxy = new LocationListenerProxy(locationListener);
//将原始的LocationListener替换为LocationListenerProxy
mListenerField.set(listenerTransport, locationListenerProxy);
mListenerField.setAccessible(false);
return method.invoke(originService, args);
} catch (Exception e) {
//处理定位权限未授予的情况
return null;
}
Object listenerTransport = args[1];
//LocationListener mListener 类型
Field mListenerField = listenerTransport.getClass().getDeclaredField("mListener");
mListenerField.setAccessible(true);
LocationListener locationListener = (LocationListener) mListenerField.get(listenerTransport);
LocationListenerProxy locationListenerProxy = new LocationListenerProxy(locationListener);
//将原始的LocationListener替换为LocationListenerProxy
mListenerField.set(listenerTransport, locationListenerProxy);
mListenerField.setAccessible(false);
return method.invoke(originService, args);
}
}
......
......@@ -32,10 +32,11 @@ import java.net.URLDecoder
* 修订历史:
* ================================================
*/
class DokitWebViewClient(webViewClient: WebViewClient?) : WebViewClient() {
class DokitWebViewClient(webViewClient: WebViewClient?, userAgent: String) : WebViewClient() {
private val TAG = "DokitWebViewClient"
private val mWebViewClient: WebViewClient? = webViewClient
private val mUserAgent = userAgent
//private val mOkHttpClient = OkHttpClient()
/**
......@@ -88,6 +89,7 @@ class DokitWebViewClient(webViewClient: WebViewClient?) : WebViewClient() {
webRequest.url?.toString() + "&dokit_flag=web"
}
val httpRequest = Request.Builder()
.header("User-Agent", mUserAgent)
.url(url)
.build()
val response = OkhttpClientUtil.okhttpClient.newCall(httpRequest).execute()
......@@ -268,12 +270,12 @@ class DokitWebViewClient(webViewClient: WebViewClient?) : WebViewClient() {
*/
private fun injectVConsoleHook(html: String?): String {
//读取本地js hook 代码
val vconsoleHook = ResourceUtils.readAssets2String("dokit_js_vconsole_hook.html")
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)
elements[elements.size - 1].append(vConsoleHook)
}
return doc.toString()
}
......
......@@ -34,10 +34,11 @@ import java.net.URLDecoder
* 修订历史:
* ================================================
*/
class DokitX5WebViewClient(webViewClient: WebViewClient?) : WebViewClient() {
class DokitX5WebViewClient(webViewClient: WebViewClient?, userAgent: String) : WebViewClient() {
private val TAG = "DokitWebViewClient"
private val mWebViewClient: WebViewClient? = webViewClient
private val mUserAgent = userAgent
/**
* 更新悬浮窗上的链接
......@@ -90,6 +91,7 @@ class DokitX5WebViewClient(webViewClient: WebViewClient?) : WebViewClient() {
}
val httpRequest = Request.Builder()
.header("User-Agent", mUserAgent)
.url(url)
.build()
val response = OkhttpClientUtil.okhttpClient.newCall(httpRequest).execute()
......
......@@ -212,15 +212,14 @@ class H5DokitView : AbsDokitView() {
return it
} else if (it is ViewGroup) {
return traversView(it)
}
}
return null
}
private fun traversView(viewGroup: ViewGroup): WebView? {
private fun traversView(viewGroup: ViewGroup): Any? {
viewGroup.children.forEach {
if (it is WebView) {
if (it is WebView || it is com.tencent.smtt.sdk.WebView) {
return it
} else if (it is ViewGroup) {
return traversView(it)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册