Skip to content

Commit

Permalink
优化WebView
Browse files Browse the repository at this point in the history
  • Loading branch information
zhujiang2 committed Aug 2, 2022
1 parent 8103ca0 commit b08ebcf
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 52 deletions.
2 changes: 0 additions & 2 deletions app/src/main/java/com/zj/play/article/ArticleActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.zj.play.article
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.PixelFormat
import android.view.KeyEvent
import android.view.View
import android.widget.ImageView
Expand Down Expand Up @@ -62,7 +61,6 @@ class ArticleActivity : BaseActivity(), View.OnClickListener {
}

override fun initView() {
window.setFormat(PixelFormat.TRANSLUCENT)
binding.articleImgBack.setOnClickListener(this)
binding.articleImgRight.setOnClickListener(this)
}
Expand Down
186 changes: 138 additions & 48 deletions app/src/main/java/com/zj/play/article/X5WebView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ package com.zj.play.article

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.net.Uri
import android.os.Build
import android.text.TextUtils
import android.util.AttributeSet
import android.util.Log
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams
import android.webkit.*
Expand All @@ -20,6 +18,7 @@ import androidx.core.content.res.ResourcesCompat
import androidx.core.view.isVisible
import com.zj.play.R


/**
* [setShowProgress]
*/
Expand All @@ -44,39 +43,48 @@ class X5WebView @JvmOverloads constructor(
progressBar?.progressDrawable =
ResourcesCompat.getDrawable(resources, R.drawable.color_progressbar, null)
addView(progressBar, LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 6))
initWebViewSettings()
setDefaultWebSettings()
}

// 基本的WebViewSetting
@SuppressLint("ClickableViewAccessibility", "SetJavaScriptEnabled")
private fun initWebViewSettings() {
setBackgroundColor(resources.getColor(R.color.article_share_bg, null))
webViewClient = client
private fun setDefaultWebSettings() {
webChromeClient = chromeClient
setDownloadListener(downloadListener)
isClickable = true
setOnTouchListener { _: View?, _: MotionEvent? -> false }
val webSetting = settings
webSetting.builtInZoomControls = true
webSetting.javaScriptCanOpenWindowsAutomatically = true
webSetting.domStorageEnabled = true
webSetting.allowFileAccess = true
webSetting.setSupportZoom(true)
webSetting.useWideViewPort = true
webSetting.setSupportMultipleWindows(true)
webSetting.setAppCacheEnabled(true)
webSetting.setGeolocationEnabled(true)

val webSettings = settings
//5.0以上开启混合模式加载
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webSettings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
}
webSettings.loadWithOverviewMode = true
webSettings.useWideViewPort = true
//允许js代码
webSettings.javaScriptEnabled = true
//允许SessionStorage/LocalStorage存储
webSettings.domStorageEnabled = true
//禁用放缩
webSettings.displayZoomControls = false
webSettings.builtInZoomControls = false
//禁用文字缩放
webSettings.textZoom = 100
//10M缓存,api 18后,系统自动管理。
webSettings.setAppCacheMaxSize((10 * 1024 * 1024).toLong())
//允许缓存,设置缓存位置
webSettings.setAppCacheEnabled(true)
webSettings.setAppCachePath(context.getDir("appcache", 0).path)
//允许WebView使用File协议
webSettings.allowFileAccess = true
//不保存密码
webSettings.savePassword = false
//设置UA
webSettings.userAgentString = webSettings.userAgentString + " playAndroid"
//自动加载图片
webSettings.loadsImagesAutomatically = true
if (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES) { //判断如果系统是深色主题
webSetting.forceDark = WebSettings.FORCE_DARK_ON //强制开启webview深色主题模式
webSettings.forceDark = WebSettings.FORCE_DARK_ON //强制开启webview深色主题模式
} else {
webSetting.forceDark = FORCE_DARK_OFF
webSettings.forceDark = FORCE_DARK_OFF
}

//需要支持多窗体还需要重写WebChromeClient.onCreateWindow
webSetting.setSupportMultipleWindows(false)
}


override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK && canGoBack()) {
goBack() // goBack()表示返回WebView的上一页面
Expand Down Expand Up @@ -104,30 +112,112 @@ class X5WebView @JvmOverloads constructor(
}
}
}
private val client: WebViewClient = object : WebViewClient() {
//当页面加载完成的时候
override fun onPageFinished(webView: WebView, url: String) {
val cookieManager = CookieManager.getInstance()
cookieManager.setAcceptCookie(true)
val endCookie = cookieManager.getCookie(url)
Log.i("TAG", "onPageFinished: endCookie : $endCookie")
CookieManager.getInstance().flush()
super.onPageFinished(webView, url)
}

override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
): Boolean {
return true
private var mTouchByUser = false

override fun loadUrl(url: String, additionalHttpHeaders: Map<String?, String?>) {
super.loadUrl(url, additionalHttpHeaders)
resetAllStateInternal(url)
}

override fun loadUrl(url: String) {
super.loadUrl(url)
resetAllStateInternal(url)
}

override fun postUrl(url: String, postData: ByteArray) {
super.postUrl(url, postData)
resetAllStateInternal(url)
}

override fun loadData(data: String, mimeType: String?, encoding: String?) {
super.loadData(data, mimeType, encoding)
resetAllStateInternal(url)
}

override fun loadDataWithBaseURL(
baseUrl: String?,
data: String,
mimeType: String?,
encoding: String?,
historyUrl: String?
) {
super.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl)
resetAllStateInternal(url)
}

override fun reload() {
super.reload()
resetAllStateInternal(url)
}

fun isTouchByUser(): Boolean {
return mTouchByUser
}

private fun resetAllStateInternal(url: String?) {
Log.w(TAG, "resetAllStateInternal: url:$url")
if (url != null && !TextUtils.isEmpty(url) && url.startsWith("javascript:")) {
return
}
resetAllState()
}

// 加载url时重置touch状态
private fun resetAllState() {
mTouchByUser = false
}

private val downloadListener =
DownloadListener { url: String?, _: String?, _: String?, _: String?, _: Long ->
val uri = Uri.parse(url)
val intent = Intent(Intent.ACTION_VIEW, uri)
context.startActivity(intent)
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> //用户按下到下一个链接加载之前,置为true
mTouchByUser = true
}
return super.onTouchEvent(event)
}

override fun setWebViewClient(client: WebViewClient) {
Log.w(TAG, "setWebViewClient: $client")
super.setWebViewClient(object : WebViewClient() {


@Deprecated("Deprecated in Java")
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
val handleByChild = client.shouldOverrideUrlLoading(view, url)
return if (handleByChild) {
// 开放client接口给上层业务调用,如果返回true,表示业务已处理。
true
} else if (!isTouchByUser()) {
// 如果业务没有处理,并且在加载过程中用户没有再次触摸屏幕,认为是301/302事件,直接交由系统处理。
super.shouldOverrideUrlLoading(view, url)
} else {
//否则,属于二次加载某个链接的情况,为了解决拼接参数丢失问题,重新调用loadUrl方法添加固有参数。
loadUrl(url)
true
}
}

override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest
): Boolean {
Log.w(TAG, "shouldOverrideUrlLoading: ${request.url}")
val handleByChild = client.shouldOverrideUrlLoading(view, request)
return if (handleByChild) {
true
} else if (!isTouchByUser()) {
return true
} else {
loadUrl(request.url.toString())
true
}
}
})
}

companion object {
private const val TAG = "X5WebView"
}

}
4 changes: 2 additions & 2 deletions config.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ ext {
compileSdkVersion : 32,
minSdkVersion : 23,
targetSdkVersion : 32,
versionCode : 26,
versionName : "4.3.2",
versionCode : 27,
versionName : "4.3.3",
testInstrumentationRunner: "androidx.test.runner.AndroidJUnitRunner",
consumerProguardFiles : 'consumer-rules.pro',
]
Expand Down

0 comments on commit b08ebcf

Please sign in to comment.