{"id":21462297,"url":"https://github.com/espoirx/easywebview","last_synced_at":"2025-04-22T16:25:10.817Z","repository":{"id":145931162,"uuid":"271152338","full_name":"EspoirX/EasyWebView","owner":"EspoirX","description":null,"archived":false,"fork":false,"pushed_at":"2020-06-12T10:20:48.000Z","size":237,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-29T16:41:32.557Z","etag":null,"topics":["html","web","webview","webview-library"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/EspoirX.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-10T01:59:42.000Z","updated_at":"2024-07-10T09:48:06.000Z","dependencies_parsed_at":null,"dependency_job_id":"c7a8b70d-3aae-4a41-b5c9-eb9648cfc2d1","html_url":"https://github.com/EspoirX/EasyWebView","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EspoirX%2FEasyWebView","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EspoirX%2FEasyWebView/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EspoirX%2FEasyWebView/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EspoirX%2FEasyWebView/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EspoirX","download_url":"https://codeload.github.com/EspoirX/EasyWebView/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250276020,"owners_count":21403789,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html","web","webview","webview-library"],"created_at":"2024-11-23T07:13:36.890Z","updated_at":"2025-04-22T16:25:10.810Z","avatar_url":"https://github.com/EspoirX.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EasyWebView\n\n## 使用说明\n\n在使用 EasyWeb 之前记得先配置一下上下文，你可以把这个操作放在 Application 中。\n\n```kotlin\n  CacheConfig.instance.context = this\n```\nCacheConfig 是一个单例，作用是用来配置一些关于缓存相关的配置，下面会说到。因为内部获取缓存文件夹的时候需要一个上下文，\n所以这里就先让它获得一下上下文，不然在使用缓存功能的时候会空指针哦。\n\n## 最简单的使用\n```kotlin\n    EasyWeb.with(this)\n        .ready()\n        .loadUrl(\"https://www.bilibili.com/\")\n```\nEasyWeb 至少要通过调用 with 方法和 ready 方法才能发起一个 WebView 请求。上面是最简单的调用，with 传入的是当前的 Activity。\n当然，你也可以这样分开写：\n```kotlin\n    val easyWeb = EasyWeb.with(this)\n        .ready()\n    easyWeb.loadUrl(\"https://www.bilibili.com/\")\n```\n\n## 指定加载布局\n```kotlin\n    EasyWeb.with(this)\n        .setWebParent(webViewLayout)\n        .ready()\n        .loadUrl(\"https://www.bilibili.com/\")\n```\n调用 setWebParent 方法可以指定 WebView 的父布局，传入的是一个 ViewGroup，setWebParent 第二个参数是 LayoutParams，默认宽高都是\nMATCH_PARENT\n\n## 生命周期管理\n```kotlin\n    EasyWeb.with(this)\n        .setWebParent(webViewLayout)\n        .lifecycle(this@MainActivity.lifecycle)\n        .ready()\n        .loadUrl(\"https://www.bilibili.com/\")\n```\n通过 lifecycle 方法传入当前 Activity 的 lifecycle ，即可自动管理 WebView 的生命周期，内部实现了 onResume，onPause 和\nonDestroy 时的处理，再也不用担心内存泄露。\n\n## WebView 缓存\n```kotlin\n    EasyWeb.with(this)\n        .setWebParent(webViewLayout)\n        .lifecycle(this@MainActivity.lifecycle)\n        .setWebCacheMode(WebCacheMode.DEFAULT)\n        .ready()\n        .loadUrl(\"https://www.bilibili.com/\")\n```\n通过 setWebCacheMode 方法即可快速实现 WebView 的缓存机制，WebCacheMode 是一个枚举，提供三种模式，NOCACHE，DEFAULT，CACHE_RES。\n分别代表着不使用缓存，使用 WebView 自带的缓存机制，以及使用自定义的缓存机制。\n\n1. WebView 自带的缓存机制 , 即通过 WebSettings 配置 WebView 自带的缓存实现。具体的代码逻辑在 BaseWebViewSetting 这个类里面。\n2. 自定义的缓存机制，主要是缓存网页中的资源文件，通过拦截 shouldInterceptRequest 方法，然后使用 OkHttp 把资源下载下来，EasyWeb\n对这些文件使用了三级缓存，并通过 Lru 算法管理，即 LruCache，DiskLruCache。\n\n缓存配置可以通过 CacheConfig 这个类，它是一个单例。如果你想缓存指定的文件，或者想某几个 url 不缓存，你可以这样配置：\n```kotlin\n    //添加指定缓存文件\n    CacheConfig.instance\n        .addCacheFile(\"html\")\n        .addCacheFile(\"js\")\n        .addCacheFile(\"css\")\n        .addCacheFile(\"jpg\")\n        .addCacheFile(\"png\")\n        .addCacheFile(\"gif\")\n\n    //添加缓存白名单\n    CacheConfig.instance\n        .addIgnoreUrl(\"baidu\")\n        .addIgnoreUrl(\"taobao\")\n        .addIgnoreUrl(\"wxpay\")\n        .addIgnoreUrl(\"alipay\")\n```\n\n## 与 JS 的交互\n\n```kotlin\n    EasyWeb.with(this)\n        .setWebParent(webViewLayout)\n        .lifecycle(this@MainActivity.lifecycle)\n        .setWebCacheMode(WebCacheMode.DEFAULT)\n        .ready()\n        .addJsInterface(JsInterfaceTest(), \"WebViewJavascriptBridge\")\n        .loadUrl(\"https://www.bilibili.com/\")\n\n    //当然也可以这样子\n    val easyWeb = EasyWeb.with(this@MainActivity)\n        .setWebParent(webViewLayout)\n        .lifecycle(this@MainActivity.lifecycle)\n        .setWebCacheMode(WebCacheMode.DEFAULT)\n        .ready()\n        .loadUrl(url)\n\n    easyWeb?.addJsInterface(JsInterfaceTest(), \"WebViewJavascriptBridge\")\n\n    class JsInterfaceTest : BaseJavascriptInterface() {\n        @JavascriptInterface\n        fun callAndroidMethod(param: String) {\n            Toast.makeText(activity, \"我是js里面传过来的参数:$param\", Toast.LENGTH_SHORT).show()\n        }\n    }\n```\n\n与 Js 的交互，比如 Js 调用客户端的方法，可以通过 addJsInterface 方法实现，addJsInterface 方法需要在 ready 方法后\n调用。该方法有两个参数，一个是 object，一个是 name，想必不需要过多的解析，object 需要继承 BaseJavascriptInterface 这个\n类，为什么？因为继承了 BaseJavascriptInterface，你就能很方便的拿到当前的 Activity 和 WebView 哦：\n\n```kotlin\nopen class BaseJavascriptInterface {\n    var activity: Activity? = null\n    var webView: IProxyWebView? = null\n}\n```\n\n那么在开发时，如果想要拿到某个 js 回调怎么办？你可以通过 getJsInterface 方法去实现：\n```kotlin\n   val easyWeb = EasyWeb.with(this)\n        .setWebParent(webViewLayout)\n        .lifecycle(this@MainActivity.lifecycle)\n        .setWebCacheMode(WebCacheMode.DEFAULT)\n        .ready()\n        .addJsInterface(JsInterfaceTest(), \"WebViewJavascriptBridge\")\n        .loadUrl(\"https://www.bilibili.com/\")\n\n    val jsObj = easyWeb?.getJsInterface(\"WebViewJavascriptBridge\")\n    Log.i(\"MainActivity\", \"jsObj = $jsObj\")\n```\n\n## 长按事件\n```kotlin\n EasyWeb.with(this@MainActivity)\n    .setWebParent(webViewLayout)\n    .lifecycle(this@MainActivity.lifecycle)\n    .setWebCacheMode(WebCacheMode.DEFAULT)\n    .setOnWebViewLongClick(object : OnWebViewLongClick {\n        override fun onClick(type: Int, hitTestResult: Any?): Boolean {\n            return false\n        }\n\n        override fun onClickWebImage(imgUrl: String?): Boolean {\n            return false\n        }\n    })\n    .ready()\n    .loadUrl(\"https://www.bilibili.com/\")\n```\n通过设置 setOnWebViewLongClick 方法，实现 OnWebViewLongClick 接口即可实现 WebView 的长按事件，该接口有两个方法，\nonClickWebImage，是长按图片的时候的回调，你可以在这里实现下载图片等逻辑，onClick，就是除了长按图片之外的其他长按类型\n事件，你可以通过两个参数去区分具体是什么类型。\n\n## WebChromeClient 与 setWebViewClient\n```kotlin\n     EasyWeb.with(this@MainActivity)\n        .setWebParent(webViewLayout)\n        .lifecycle(this@MainActivity.lifecycle)\n        .setWebCacheMode(WebCacheMode.DEFAULT)\n        .setWebChromeClient(object : WebChromeClient() {\n\n        })\n        .setWebViewClient(object : WebViewClient() {\n\n        })\n        .ready()\n        .loadUrl(\"https://www.bilibili.com/\")\n```\n设置 WebChromeClient 与 setWebViewClient 很简单，就是通过 setWebChromeClient 和 setWebViewClient 两个方法，跟\n使用 WebView 时一样，但 EasyWeb 内部通过代理已经实现好了两个默认的 WebChromeClient 和 WebViewClient，并且把一些重定向\n等问题解决了，用户不需要去管理，只需要跟正常使用一样使用 WebChromeClient 和 WebViewClient 即可。\n\n## 配置 WebSettings\n```kotlin\n    EasyWeb.with(this@MainActivity)\n        .setWebParent(webViewLayout)\n        .setWebViewSetting(MyWebSetting())\n        .ready()\n        .loadUrl(\"https://www.bilibili.com/\")\n\n    class MyWebSetting : BaseWebViewSetting() {\n        override fun setUpSetting(webSettings: WebSettings?) {\n            //...\n        }\n    }\n```\n通过 setWebViewSetting 方法，即可配置自己的 WebSettings，你只需要继承 BaseWebViewSetting 这个类，并且在方法 setUpSetting 中\n拿到 webSettings 对象，即可实现你自己的 WebSettings，当然，EasyWeb 默认的 WebSettings 在 DefaultWebSettings 这个类中\n配置，并且已经移除了有风险的隐藏接口：\n```kotlin\n    removeJavascriptInterface(\"searchBoxJavaBridge_\")\n    removeJavascriptInterface(\"accessibility\")\n    removeJavascriptInterface(\"accessibilityTraversal\")\n```\n\n## 添加加载出错时的界面\n```kotlin\n   val errorView = TextView(this)\n    errorView.layoutParams = ViewGroup.LayoutParams(\n        ViewGroup.LayoutParams.MATCH_PARENT,\n        ViewGroup.LayoutParams.MATCH_PARENT\n    )\n    errorView.gravity = Gravity.CENTER\n    errorView.text = \"出错了\"\n\n    EasyWeb.with(this@MainActivity)\n        .setWebParent(webViewLayout)\n        .addErrorView(errorView)\n        .ready()\n        .loadUrl(\"https://www.bilibili.com/\")\n```\n通过 addErrorView 即可添加你的网页加载失败时显示的界面。addErrorView 第二个参数是一个 view 的 id，作用是当点击这个 view 时，\n会触发 reload 操作。如果不传，或者传 -1，那么点击整个 view 是会触发 reload 操作。\naddErrorView 除了传入 view 之外，还可以传入 layoutId，和 url。\n\n## IUrlLoader 和 IJsLoader\n```kotlin\n    EasyWeb.with(this@MainActivity)\n        .setWebParent(webViewLayout)\n        .setUrlLoader(MyUrlLooader())\n        .setJsLoader(MyJsLooader())\n        .ready()\n        .loadUrl(\"https://www.bilibili.com/\")\n```\n在调用 WebView 的 loadUrl 或者其他加载网页的方法时，很多时候需要做一些其他操作，所以 EasyWeb 提供了两个接口专门去隔离这些操作，\n让你可以在调用实际的 loadUrl 前做一些自己的逻辑，并且达到解耦的效果。通过 setUrlLoader 和 setJsLoader 方法配置即可。\n可以通过查看代码中的 IUrlLoader 和 IJsLoader 文件查看这两个接口的定义以及默认的实现。\n\n# 其他方法\nEasyWeb 除了以上一些配置，通过 EasyWeb 对象你也可以获得很多东西，具体可以查看 EasyWeb 这个类的实现哦。\n\nEasyWeb 是参考了很多优秀的 WebView 库之后产生的，感谢这些开源库。期待你的意见，喜欢就点个 star 把。^_^","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fespoirx%2Feasywebview","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fespoirx%2Feasywebview","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fespoirx%2Feasywebview/lists"}