参考链接:Loading in-app content | Android Developers (google.cn)
需要添加依赖:implementation 'androidx.webkit:webkit:1.4.0'
使用WebViewAssetLoader
加载离线资源可以避免直接通过file://xxx 协议加载本地资源请求接口产生的跨域问题,以及使用file协议可能产生的安全问题,WebViewAssetLoader
也是google官方推荐加载离线资源的方式
WebViewAssetLoader内置了三个对象来帮助开发者加载离线资源
内置对象 | 作用 |
---|---|
InternalStoragePathHandler | data/data/${applicationId}/下面的资源 |
AssetsPathHandler | apk里面assets中的资源 |
ResourcesPathHandler | apk里面res中的资源 |
下面一InternalStoragePathHandler
为例展示离线加载data/data/${applicationId}/files/webApp/
中的内容
class DemoActivity : AppCompatActivity() {
private val TAG: String = "DemoActivity"
lateinit var webView: WebView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_demo)
val webContainer = findViewById<FrameLayout>(R.id.webContainer)
webView = WebView(this)
webContainer.addView(
webView,
FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
)
initWebView()
//加载页面
webView.loadUrl("https://www.baidu.com/index.html")
}
private fun initWebView() {
WebView.setWebContentsDebuggingEnabled(true)
//离线资源路径
val publicDir = File(filesDir, "webApp")
Log.d(TAG, "filesDir:${filesDir.absolutePath}")
val webViewAssetLoader = WebViewAssetLoader.Builder()
.setDomain("www.baidu.com")//设置域名,在该域名优先适用离线资源,离线资源不可以用时再使用在线资源
.addPathHandler("/", WebViewAssetLoader.InternalStoragePathHandler(this, publicDir))//对所有资源优先检查离线资源
.build()
webView.webViewClient = OffLineWebViewClient(webViewAssetLoader)
webView.isClickable = true
//webView的一些常见设置
webView.setOnTouchListener { v: View?, event: MotionEvent? -> false }
val webSetting = webView.settings
webSetting.javaScriptEnabled = true
webSetting.javaScriptCanOpenWindowsAutomatically = true
webSetting.domStorageEnabled = true
}
override fun onBackPressed() {
if (webView.canGoBack()) {
webView.goBack()
return
}
super.onBackPressed()
}
override fun onDestroy() {
super.onDestroy()
webView.destroy()
}
}
OffLineWebViewClient
class OffLineWebViewClient(private val assetLoader: WebViewAssetLoader) : WebViewClientCompat() {
override fun shouldInterceptRequest(
view: WebView,
request: WebResourceRequest
): WebResourceResponse? {
return assetLoader.shouldInterceptRequest(request.url)
}
}
离线资源index.html
<html>
<body>
<div style="font-size: 18px;">helle world</div>
</body>
</html>
离线资源目录data/data/${applicationId}/files/webApp/index.html
离线文件可以通过下载从静态资源zip包,然后解压到对应目录。
运行效果(即使没有网络的情况下也能正常加载离线资源)