Skip to content

Commit b08ebcf

Browse files
author
zhujiang2
committed
优化WebView
1 parent 8103ca0 commit b08ebcf

File tree

3 files changed

+140
-52
lines changed

3 files changed

+140
-52
lines changed

app/src/main/java/com/zj/play/article/ArticleActivity.kt

-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package com.zj.play.article
33
import android.content.Context
44
import android.content.Intent
55
import android.graphics.Color
6-
import android.graphics.PixelFormat
76
import android.view.KeyEvent
87
import android.view.View
98
import android.widget.ImageView
@@ -62,7 +61,6 @@ class ArticleActivity : BaseActivity(), View.OnClickListener {
6261
}
6362

6463
override fun initView() {
65-
window.setFormat(PixelFormat.TRANSLUCENT)
6664
binding.articleImgBack.setOnClickListener(this)
6765
binding.articleImgRight.setOnClickListener(this)
6866
}

app/src/main/java/com/zj/play/article/X5WebView.kt

+138-48
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@ package com.zj.play.article
22

33
import android.annotation.SuppressLint
44
import android.content.Context
5-
import android.content.Intent
65
import android.content.res.Configuration
7-
import android.net.Uri
6+
import android.os.Build
87
import android.text.TextUtils
98
import android.util.AttributeSet
109
import android.util.Log
1110
import android.view.KeyEvent
1211
import android.view.MotionEvent
13-
import android.view.View
1412
import android.view.ViewGroup
1513
import android.view.ViewGroup.LayoutParams
1614
import android.webkit.*
@@ -20,6 +18,7 @@ import androidx.core.content.res.ResourcesCompat
2018
import androidx.core.view.isVisible
2119
import com.zj.play.R
2220

21+
2322
/**
2423
* [setShowProgress]
2524
*/
@@ -44,39 +43,48 @@ class X5WebView @JvmOverloads constructor(
4443
progressBar?.progressDrawable =
4544
ResourcesCompat.getDrawable(resources, R.drawable.color_progressbar, null)
4645
addView(progressBar, LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 6))
47-
initWebViewSettings()
46+
setDefaultWebSettings()
4847
}
4948

50-
// 基本的WebViewSetting
51-
@SuppressLint("ClickableViewAccessibility", "SetJavaScriptEnabled")
52-
private fun initWebViewSettings() {
53-
setBackgroundColor(resources.getColor(R.color.article_share_bg, null))
54-
webViewClient = client
49+
private fun setDefaultWebSettings() {
5550
webChromeClient = chromeClient
56-
setDownloadListener(downloadListener)
57-
isClickable = true
58-
setOnTouchListener { _: View?, _: MotionEvent? -> false }
59-
val webSetting = settings
60-
webSetting.builtInZoomControls = true
61-
webSetting.javaScriptCanOpenWindowsAutomatically = true
62-
webSetting.domStorageEnabled = true
63-
webSetting.allowFileAccess = true
64-
webSetting.setSupportZoom(true)
65-
webSetting.useWideViewPort = true
66-
webSetting.setSupportMultipleWindows(true)
67-
webSetting.setAppCacheEnabled(true)
68-
webSetting.setGeolocationEnabled(true)
69-
51+
val webSettings = settings
52+
//5.0以上开启混合模式加载
53+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
54+
webSettings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
55+
}
56+
webSettings.loadWithOverviewMode = true
57+
webSettings.useWideViewPort = true
58+
//允许js代码
59+
webSettings.javaScriptEnabled = true
60+
//允许SessionStorage/LocalStorage存储
61+
webSettings.domStorageEnabled = true
62+
//禁用放缩
63+
webSettings.displayZoomControls = false
64+
webSettings.builtInZoomControls = false
65+
//禁用文字缩放
66+
webSettings.textZoom = 100
67+
//10M缓存,api 18后,系统自动管理。
68+
webSettings.setAppCacheMaxSize((10 * 1024 * 1024).toLong())
69+
//允许缓存,设置缓存位置
70+
webSettings.setAppCacheEnabled(true)
71+
webSettings.setAppCachePath(context.getDir("appcache", 0).path)
72+
//允许WebView使用File协议
73+
webSettings.allowFileAccess = true
74+
//不保存密码
75+
webSettings.savePassword = false
76+
//设置UA
77+
webSettings.userAgentString = webSettings.userAgentString + " playAndroid"
78+
//自动加载图片
79+
webSettings.loadsImagesAutomatically = true
7080
if (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES) { //判断如果系统是深色主题
71-
webSetting.forceDark = WebSettings.FORCE_DARK_ON //强制开启webview深色主题模式
81+
webSettings.forceDark = WebSettings.FORCE_DARK_ON //强制开启webview深色主题模式
7282
} else {
73-
webSetting.forceDark = FORCE_DARK_OFF
83+
webSettings.forceDark = FORCE_DARK_OFF
7484
}
75-
76-
//需要支持多窗体还需要重写WebChromeClient.onCreateWindow
77-
webSetting.setSupportMultipleWindows(false)
7885
}
7986

87+
8088
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
8189
if (keyCode == KeyEvent.KEYCODE_BACK && canGoBack()) {
8290
goBack() // goBack()表示返回WebView的上一页面
@@ -104,30 +112,112 @@ class X5WebView @JvmOverloads constructor(
104112
}
105113
}
106114
}
107-
private val client: WebViewClient = object : WebViewClient() {
108-
//当页面加载完成的时候
109-
override fun onPageFinished(webView: WebView, url: String) {
110-
val cookieManager = CookieManager.getInstance()
111-
cookieManager.setAcceptCookie(true)
112-
val endCookie = cookieManager.getCookie(url)
113-
Log.i("TAG", "onPageFinished: endCookie : $endCookie")
114-
CookieManager.getInstance().flush()
115-
super.onPageFinished(webView, url)
116-
}
117115

118-
override fun shouldOverrideUrlLoading(
119-
view: WebView?,
120-
request: WebResourceRequest?
121-
): Boolean {
122-
return true
116+
private var mTouchByUser = false
117+
118+
override fun loadUrl(url: String, additionalHttpHeaders: Map<String?, String?>) {
119+
super.loadUrl(url, additionalHttpHeaders)
120+
resetAllStateInternal(url)
121+
}
122+
123+
override fun loadUrl(url: String) {
124+
super.loadUrl(url)
125+
resetAllStateInternal(url)
126+
}
127+
128+
override fun postUrl(url: String, postData: ByteArray) {
129+
super.postUrl(url, postData)
130+
resetAllStateInternal(url)
131+
}
132+
133+
override fun loadData(data: String, mimeType: String?, encoding: String?) {
134+
super.loadData(data, mimeType, encoding)
135+
resetAllStateInternal(url)
136+
}
137+
138+
override fun loadDataWithBaseURL(
139+
baseUrl: String?,
140+
data: String,
141+
mimeType: String?,
142+
encoding: String?,
143+
historyUrl: String?
144+
) {
145+
super.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl)
146+
resetAllStateInternal(url)
147+
}
148+
149+
override fun reload() {
150+
super.reload()
151+
resetAllStateInternal(url)
152+
}
153+
154+
fun isTouchByUser(): Boolean {
155+
return mTouchByUser
156+
}
157+
158+
private fun resetAllStateInternal(url: String?) {
159+
Log.w(TAG, "resetAllStateInternal: url:$url")
160+
if (url != null && !TextUtils.isEmpty(url) && url.startsWith("javascript:")) {
161+
return
123162
}
163+
resetAllState()
164+
}
124165

166+
// 加载url时重置touch状态
167+
private fun resetAllState() {
168+
mTouchByUser = false
125169
}
126170

127-
private val downloadListener =
128-
DownloadListener { url: String?, _: String?, _: String?, _: String?, _: Long ->
129-
val uri = Uri.parse(url)
130-
val intent = Intent(Intent.ACTION_VIEW, uri)
131-
context.startActivity(intent)
171+
@SuppressLint("ClickableViewAccessibility")
172+
override fun onTouchEvent(event: MotionEvent): Boolean {
173+
when (event.action) {
174+
MotionEvent.ACTION_DOWN -> //用户按下到下一个链接加载之前,置为true
175+
mTouchByUser = true
132176
}
177+
return super.onTouchEvent(event)
178+
}
179+
180+
override fun setWebViewClient(client: WebViewClient) {
181+
Log.w(TAG, "setWebViewClient: $client")
182+
super.setWebViewClient(object : WebViewClient() {
183+
184+
185+
@Deprecated("Deprecated in Java")
186+
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
187+
val handleByChild = client.shouldOverrideUrlLoading(view, url)
188+
return if (handleByChild) {
189+
// 开放client接口给上层业务调用,如果返回true,表示业务已处理。
190+
true
191+
} else if (!isTouchByUser()) {
192+
// 如果业务没有处理,并且在加载过程中用户没有再次触摸屏幕,认为是301/302事件,直接交由系统处理。
193+
super.shouldOverrideUrlLoading(view, url)
194+
} else {
195+
//否则,属于二次加载某个链接的情况,为了解决拼接参数丢失问题,重新调用loadUrl方法添加固有参数。
196+
loadUrl(url)
197+
true
198+
}
199+
}
200+
201+
override fun shouldOverrideUrlLoading(
202+
view: WebView?,
203+
request: WebResourceRequest
204+
): Boolean {
205+
Log.w(TAG, "shouldOverrideUrlLoading: ${request.url}")
206+
val handleByChild = client.shouldOverrideUrlLoading(view, request)
207+
return if (handleByChild) {
208+
true
209+
} else if (!isTouchByUser()) {
210+
return true
211+
} else {
212+
loadUrl(request.url.toString())
213+
true
214+
}
215+
}
216+
})
217+
}
218+
219+
companion object {
220+
private const val TAG = "X5WebView"
221+
}
222+
133223
}

config.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ ext {
33
compileSdkVersion : 32,
44
minSdkVersion : 23,
55
targetSdkVersion : 32,
6-
versionCode : 26,
7-
versionName : "4.3.2",
6+
versionCode : 27,
7+
versionName : "4.3.3",
88
testInstrumentationRunner: "androidx.test.runner.AndroidJUnitRunner",
99
consumerProguardFiles : 'consumer-rules.pro',
1010
]

0 commit comments

Comments
 (0)