[{"data":1,"prerenderedAt":1195},["ShallowReactive",2],{"navigation":3,"post-\u002Fposts\u002F2020\u002Fandroid-webview-picture-cache":20,"surroundPosts-\u002Fposts\u002F2020\u002Fandroid-webview-picture-cache":1183},[4,8,12,16],{"title":5,"path":6,"stem":7},"首页","\u002F","00.index",{"title":9,"path":10,"stem":11},"文章","\u002Fposts","01.posts",{"title":13,"path":14,"stem":15},"动态","\u002Fmoments","02.moments",{"title":17,"path":18,"stem":19},"关于","\u002Fabout","09.about",{"id":21,"title":22,"body":23,"class":1164,"cover":1165,"coverSize":1164,"date":1166,"description":29,"draft":1167,"extension":1168,"hideComments":1167,"location":1164,"meta":1169,"navigation":168,"path":1170,"readingTime":1171,"seo":1176,"sitemap":1177,"stem":1178,"tags":1179,"time":1164,"weather":1164,"__hash__":1182},"posts\u002Fposts\u002F2020\u002F20201218.android-webview-picture-cache.md","安卓 WebView 图片离线缓存方案",{"type":24,"value":25,"toc":1162},"minimark",[26,30,33,36,62,65,1158],[27,28,29],"p",{},"有这样一个项目，UI 渲染全部由 WebView 来完成，套个安卓的壳，壳子里面做一些和硬件交互的功能，例如摄像头、麦克风等。WebView 加载的页面走的本地打包的文件。不过 WebView 中的图片等资源走的是网络访问。",[27,31,32],{},"为了减少网络访问的流量，以及提升在弱网络或无网络情况下的体验，需要对网络访问的图片进行本地缓存。",[27,34,35],{},"原先采用的是 WebView 自带的缓存机制来实现，但并不可靠，于是需要通过拦截网络请求，通过本地缓存干预的方式来实现。具体原理如下：",[37,38,39,48,59],"ol",{},[40,41,42,43,47],"li",{},"通过 ",[44,45,46],"code",{},"shouldInterceptRequest"," 拦截请求，判断是否是访问网络图片，如果是则进行干预",[40,49,50,51,54,55,58],{},"取请求地址的 ",[44,52,53],{},"md5"," 值加图片文件扩展名组成的文件名，拼接 ",[44,56,57],{},"cache"," 目录获得一个本地资源地址，判断该资源是否存在，若存在则直接返回该资源",[40,60,61],{},"若该资源不存在，说明是首次访问，则将该网络图片下载到该地址下，并返回该资源",[27,63,64],{},"具体代码如下：",[66,67,72],"pre",{"className":68,"code":69,"language":70,"meta":71,"style":71},"language-kotlin shiki shiki-themes material-theme-lighter github-light github-dark","import android.content.Context\nimport android.net.http.SslError\nimport android.webkit.*\nimport androidx.webkit.WebViewAssetLoader\nimport java.io.File\nimport java.io.FileOutputStream\nimport java.math.BigInteger\nimport java.net.HttpURLConnection\nimport java.net.URL\nimport java.security.MessageDigest\n\nclass CommonWebClient(context: Context) : WebViewClient() {\n    private var assetLoader: WebViewAssetLoader = WebViewAssetLoader.Builder()\n            .addPathHandler(\"\u002Fassets\u002F\", WebViewAssetLoader.AssetsPathHandler(context))\n            .build()\n\n    private fun md5(input: String): String {\n        return BigInteger(1, MessageDigest.getInstance(\"MD5\").digest(input.toByteArray())).toString(16).padStart(32, '0')\n    }\n\n    override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {\n        return true\n    }\n\n    override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? {\n        return request?.url?.let { url ->\n            val urlString = url.toString()\n            if (!urlString.contains(\"appassets.androidplatform.net\") && urlString.contains(\"aliyuncs.com\")) {\n                try {\n                    var extension = urlString.substring(urlString.lastIndexOf(\".\"))\n                    if (extension.lastIndexOf(\"?\") > -1) {\n                        extension = extension.substring(0, extension.lastIndexOf(\"?\"))\n                    }\n                    val fileName = \"${md5(urlString)}${extension}\"\n                    val file = File(view?.context?.externalCacheDir, fileName)\n                    if (!file.exists()) {\n                        val conn = URL(urlString).openConnection() as HttpURLConnection\n                        conn.connectTimeout = 5000\n                        conn.requestMethod = \"GET\"\n                        conn.doInput = true\n                        if (conn.responseCode == 200) {\n                            val fos = FileOutputStream(file)\n                            val buffer = ByteArray(1024)\n                            var len = 0\n                            while (conn.inputStream.read(buffer).also { len = it } != -1) {\n                                fos.write(buffer, 0, len)\n                            }\n                            conn.inputStream.close()\n                            fos.close()\n                        }\n                    }\n                    WebResourceResponse(MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension), \"UTF-8\", file.inputStream())\n                } catch (ex: Exception) {\n                    assetLoader.shouldInterceptRequest(url)\n                }\n            } else {\n                val response = assetLoader.shouldInterceptRequest(url)\n                if (url.path?.endsWith(\".js\") == true && response != null) {\n                    response.mimeType = \"text\u002Fjavascript\"\n                }\n                response\n            }\n        }\n    }\n\n    override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler?, error: SslError?) {\n        handler?.proceed()\n        super.onReceivedSslError(view, handler, error)\n    }\n}\n","kotlin","",[44,73,74,87,95,107,115,123,131,139,147,155,163,170,195,224,249,259,264,289,358,364,369,398,407,412,417,446,463,482,524,532,562,591,620,626,662,678,696,725,736,747,757,774,791,811,825,860,877,883,894,904,910,915,948,965,976,982,993,1011,1048,1059,1064,1070,1076,1082,1087,1092,1121,1132,1147,1152],{"__ignoreMap":71},[75,76,79,83],"span",{"class":77,"line":78},"line",1,[75,80,82],{"class":81},"smGrS","import",[75,84,86],{"class":85},"sbgvK"," android.content.Context\n",[75,88,90,92],{"class":77,"line":89},2,[75,91,82],{"class":81},[75,93,94],{"class":85}," android.net.http.SslError\n",[75,96,98,100,103],{"class":77,"line":97},3,[75,99,82],{"class":81},[75,101,102],{"class":85}," android.webkit.",[75,104,106],{"class":105},"s_hVV","*\n",[75,108,110,112],{"class":77,"line":109},4,[75,111,82],{"class":81},[75,113,114],{"class":85}," androidx.webkit.WebViewAssetLoader\n",[75,116,118,120],{"class":77,"line":117},5,[75,119,82],{"class":81},[75,121,122],{"class":85}," java.io.File\n",[75,124,126,128],{"class":77,"line":125},6,[75,127,82],{"class":81},[75,129,130],{"class":85}," java.io.FileOutputStream\n",[75,132,134,136],{"class":77,"line":133},7,[75,135,82],{"class":81},[75,137,138],{"class":85}," java.math.BigInteger\n",[75,140,142,144],{"class":77,"line":141},8,[75,143,82],{"class":81},[75,145,146],{"class":85}," java.net.HttpURLConnection\n",[75,148,150,152],{"class":77,"line":149},9,[75,151,82],{"class":81},[75,153,154],{"class":85}," java.net.URL\n",[75,156,158,160],{"class":77,"line":157},10,[75,159,82],{"class":81},[75,161,162],{"class":85}," java.security.MessageDigest\n",[75,164,166],{"class":77,"line":165},11,[75,167,169],{"emptyLinePlaceholder":168},true,"\n",[75,171,173,176,179,183,186,189,192],{"class":77,"line":172},12,[75,174,175],{"class":81},"class",[75,177,178],{"class":85}," CommonWebClient",[75,180,182],{"class":181},"su5hD","(context: ",[75,184,185],{"class":85},"Context",[75,187,188],{"class":181},") : ",[75,190,191],{"class":85},"WebViewClient",[75,193,194],{"class":181},"() {\n",[75,196,198,202,205,208,211,214,217,221],{"class":77,"line":197},13,[75,199,201],{"class":200},"sbsja","    private",[75,203,204],{"class":81}," var",[75,206,207],{"class":181}," assetLoader: ",[75,209,210],{"class":85},"WebViewAssetLoader",[75,212,213],{"class":81}," =",[75,215,216],{"class":181}," WebViewAssetLoader.",[75,218,220],{"class":219},"sGLFI","Builder",[75,222,223],{"class":181},"()\n",[75,225,227,230,233,236,240,243,246],{"class":77,"line":226},14,[75,228,229],{"class":181},"            .",[75,231,232],{"class":219},"addPathHandler",[75,234,235],{"class":181},"(",[75,237,239],{"class":238},"s_sjI","\"\u002Fassets\u002F\"",[75,241,242],{"class":181},", WebViewAssetLoader.",[75,244,245],{"class":219},"AssetsPathHandler",[75,247,248],{"class":181},"(context))\n",[75,250,252,254,257],{"class":77,"line":251},15,[75,253,229],{"class":181},[75,255,256],{"class":219},"build",[75,258,223],{"class":181},[75,260,262],{"class":77,"line":261},16,[75,263,169],{"emptyLinePlaceholder":168},[75,265,267,269,272,275,278,281,284,286],{"class":77,"line":266},17,[75,268,201],{"class":200},[75,270,271],{"class":81}," fun",[75,273,274],{"class":219}," md5",[75,276,277],{"class":181},"(input: ",[75,279,280],{"class":85},"String",[75,282,283],{"class":181},"): ",[75,285,280],{"class":85},[75,287,288],{"class":181}," {\n",[75,290,292,296,299,301,305,308,311,313,316,319,322,325,328,331,334,336,339,341,344,346,349,352,355],{"class":77,"line":291},18,[75,293,295],{"class":294},"sVHd0","        return",[75,297,298],{"class":219}," BigInteger",[75,300,235],{"class":181},[75,302,304],{"class":303},"srdBf","1",[75,306,307],{"class":181},", MessageDigest.",[75,309,310],{"class":219},"getInstance",[75,312,235],{"class":181},[75,314,315],{"class":238},"\"MD5\"",[75,317,318],{"class":181},").",[75,320,321],{"class":219},"digest",[75,323,324],{"class":181},"(input.",[75,326,327],{"class":219},"toByteArray",[75,329,330],{"class":181},"())).",[75,332,333],{"class":219},"toString",[75,335,235],{"class":181},[75,337,338],{"class":303},"16",[75,340,318],{"class":181},[75,342,343],{"class":219},"padStart",[75,345,235],{"class":181},[75,347,348],{"class":303},"32",[75,350,351],{"class":181},", ",[75,353,354],{"class":238},"'0'",[75,356,357],{"class":181},")\n",[75,359,361],{"class":77,"line":360},19,[75,362,363],{"class":181},"    }\n",[75,365,367],{"class":77,"line":366},20,[75,368,169],{"emptyLinePlaceholder":168},[75,370,372,375,377,380,383,386,389,391,393,396],{"class":77,"line":371},21,[75,373,374],{"class":200},"    override",[75,376,271],{"class":81},[75,378,379],{"class":219}," shouldOverrideUrlLoading",[75,381,382],{"class":181},"(view: ",[75,384,385],{"class":85},"WebView",[75,387,388],{"class":181},", url: ",[75,390,280],{"class":85},[75,392,283],{"class":181},[75,394,395],{"class":85},"Boolean",[75,397,288],{"class":181},[75,399,401,403],{"class":77,"line":400},22,[75,402,295],{"class":294},[75,404,406],{"class":405},"syTEX"," true\n",[75,408,410],{"class":77,"line":409},23,[75,411,363],{"class":181},[75,413,415],{"class":77,"line":414},24,[75,416,169],{"emptyLinePlaceholder":168},[75,418,420,422,424,427,429,431,434,437,440,443],{"class":77,"line":419},25,[75,421,374],{"class":200},[75,423,271],{"class":81},[75,425,426],{"class":219}," shouldInterceptRequest",[75,428,382],{"class":181},[75,430,385],{"class":85},[75,432,433],{"class":181},"?, request: ",[75,435,436],{"class":85},"WebResourceRequest",[75,438,439],{"class":181},"?): ",[75,441,442],{"class":85},"WebResourceResponse",[75,444,445],{"class":181},"? {\n",[75,447,449,451,454,457,460],{"class":77,"line":448},26,[75,450,295],{"class":294},[75,452,453],{"class":181}," request?.url?.",[75,455,456],{"class":219},"let",[75,458,459],{"class":181}," { url ",[75,461,462],{"class":200},"->\n",[75,464,466,469,472,475,478,480],{"class":77,"line":465},27,[75,467,468],{"class":81},"            val",[75,470,471],{"class":181}," urlString ",[75,473,474],{"class":81},"=",[75,476,477],{"class":181}," url.",[75,479,333],{"class":219},[75,481,223],{"class":181},[75,483,485,488,491,494,497,500,502,505,508,511,514,516,518,521],{"class":77,"line":484},28,[75,486,487],{"class":294},"            if",[75,489,490],{"class":181}," (",[75,492,493],{"class":81},"!",[75,495,496],{"class":181},"urlString.",[75,498,499],{"class":219},"contains",[75,501,235],{"class":181},[75,503,504],{"class":238},"\"appassets.androidplatform.net\"",[75,506,507],{"class":181},") ",[75,509,510],{"class":81},"&&",[75,512,513],{"class":181}," urlString.",[75,515,499],{"class":219},[75,517,235],{"class":181},[75,519,520],{"class":238},"\"aliyuncs.com\"",[75,522,523],{"class":181},")) {\n",[75,525,527,530],{"class":77,"line":526},29,[75,528,529],{"class":294},"                try",[75,531,288],{"class":181},[75,533,535,538,541,543,545,548,551,554,556,559],{"class":77,"line":534},30,[75,536,537],{"class":81},"                    var",[75,539,540],{"class":181}," extension ",[75,542,474],{"class":81},[75,544,513],{"class":181},[75,546,547],{"class":219},"substring",[75,549,550],{"class":181},"(urlString.",[75,552,553],{"class":219},"lastIndexOf",[75,555,235],{"class":181},[75,557,558],{"class":238},"\".\"",[75,560,561],{"class":181},"))\n",[75,563,565,568,571,573,575,578,580,583,586,588],{"class":77,"line":564},31,[75,566,567],{"class":294},"                    if",[75,569,570],{"class":181}," (extension.",[75,572,553],{"class":219},[75,574,235],{"class":181},[75,576,577],{"class":238},"\"?\"",[75,579,507],{"class":181},[75,581,582],{"class":81},">",[75,584,585],{"class":81}," -",[75,587,304],{"class":303},[75,589,590],{"class":181},") {\n",[75,592,594,597,599,602,604,606,609,612,614,616,618],{"class":77,"line":593},32,[75,595,596],{"class":181},"                        extension ",[75,598,474],{"class":81},[75,600,601],{"class":181}," extension.",[75,603,547],{"class":219},[75,605,235],{"class":181},[75,607,608],{"class":303},"0",[75,610,611],{"class":181},", extension.",[75,613,553],{"class":219},[75,615,235],{"class":181},[75,617,577],{"class":238},[75,619,561],{"class":181},[75,621,623],{"class":77,"line":622},33,[75,624,625],{"class":181},"                    }\n",[75,627,629,632,635,637,640,644,646,650,653,656,659],{"class":77,"line":628},34,[75,630,631],{"class":81},"                    val",[75,633,634],{"class":181}," fileName ",[75,636,474],{"class":81},[75,638,639],{"class":238}," \"",[75,641,643],{"class":642},"sjJ54","${",[75,645,53],{"class":219},[75,647,649],{"class":648},"sfo-9","(urlString)",[75,651,652],{"class":642},"}${",[75,654,655],{"class":648},"extension",[75,657,658],{"class":642},"}",[75,660,661],{"class":238},"\"\n",[75,663,665,667,670,672,675],{"class":77,"line":664},35,[75,666,631],{"class":81},[75,668,669],{"class":181}," file ",[75,671,474],{"class":81},[75,673,674],{"class":219}," File",[75,676,677],{"class":181},"(view?.context?.externalCacheDir, fileName)\n",[75,679,681,683,685,687,690,693],{"class":77,"line":680},36,[75,682,567],{"class":294},[75,684,490],{"class":181},[75,686,493],{"class":81},[75,688,689],{"class":181},"file.",[75,691,692],{"class":219},"exists",[75,694,695],{"class":181},"()) {\n",[75,697,699,702,705,707,710,713,716,719,722],{"class":77,"line":698},37,[75,700,701],{"class":81},"                        val",[75,703,704],{"class":181}," conn ",[75,706,474],{"class":81},[75,708,709],{"class":219}," URL",[75,711,712],{"class":181},"(urlString).",[75,714,715],{"class":219},"openConnection",[75,717,718],{"class":181},"() ",[75,720,721],{"class":81},"as",[75,723,724],{"class":181}," HttpURLConnection\n",[75,726,728,731,733],{"class":77,"line":727},38,[75,729,730],{"class":181},"                        conn.connectTimeout ",[75,732,474],{"class":81},[75,734,735],{"class":303}," 5000\n",[75,737,739,742,744],{"class":77,"line":738},39,[75,740,741],{"class":181},"                        conn.requestMethod ",[75,743,474],{"class":81},[75,745,746],{"class":238}," \"GET\"\n",[75,748,750,753,755],{"class":77,"line":749},40,[75,751,752],{"class":181},"                        conn.doInput ",[75,754,474],{"class":81},[75,756,406],{"class":405},[75,758,760,763,766,769,772],{"class":77,"line":759},41,[75,761,762],{"class":294},"                        if",[75,764,765],{"class":181}," (conn.responseCode ",[75,767,768],{"class":81},"==",[75,770,771],{"class":303}," 200",[75,773,590],{"class":181},[75,775,777,780,783,785,788],{"class":77,"line":776},42,[75,778,779],{"class":81},"                            val",[75,781,782],{"class":181}," fos ",[75,784,474],{"class":81},[75,786,787],{"class":219}," FileOutputStream",[75,789,790],{"class":181},"(file)\n",[75,792,794,796,799,801,804,806,809],{"class":77,"line":793},43,[75,795,779],{"class":81},[75,797,798],{"class":181}," buffer ",[75,800,474],{"class":81},[75,802,803],{"class":219}," ByteArray",[75,805,235],{"class":181},[75,807,808],{"class":303},"1024",[75,810,357],{"class":181},[75,812,814,817,820,822],{"class":77,"line":813},44,[75,815,816],{"class":81},"                            var",[75,818,819],{"class":181}," len ",[75,821,474],{"class":81},[75,823,824],{"class":303}," 0\n",[75,826,828,831,834,837,840,843,846,848,851,854,856,858],{"class":77,"line":827},45,[75,829,830],{"class":294},"                            while",[75,832,833],{"class":181}," (conn.inputStream.",[75,835,836],{"class":219},"read",[75,838,839],{"class":181},"(buffer).",[75,841,842],{"class":219},"also",[75,844,845],{"class":181}," { len ",[75,847,474],{"class":81},[75,849,850],{"class":181}," it } ",[75,852,853],{"class":81},"!=",[75,855,585],{"class":81},[75,857,304],{"class":303},[75,859,590],{"class":181},[75,861,863,866,869,872,874],{"class":77,"line":862},46,[75,864,865],{"class":181},"                                fos.",[75,867,868],{"class":219},"write",[75,870,871],{"class":181},"(buffer, ",[75,873,608],{"class":303},[75,875,876],{"class":181},", len)\n",[75,878,880],{"class":77,"line":879},47,[75,881,882],{"class":181},"                            }\n",[75,884,886,889,892],{"class":77,"line":885},48,[75,887,888],{"class":181},"                            conn.inputStream.",[75,890,891],{"class":219},"close",[75,893,223],{"class":181},[75,895,897,900,902],{"class":77,"line":896},49,[75,898,899],{"class":181},"                            fos.",[75,901,891],{"class":219},[75,903,223],{"class":181},[75,905,907],{"class":77,"line":906},50,[75,908,909],{"class":181},"                        }\n",[75,911,913],{"class":77,"line":912},51,[75,914,625],{"class":181},[75,916,918,921,924,927,930,933,936,939,942,945],{"class":77,"line":917},52,[75,919,920],{"class":219},"                    WebResourceResponse",[75,922,923],{"class":181},"(MimeTypeMap.",[75,925,926],{"class":219},"getSingleton",[75,928,929],{"class":181},"().",[75,931,932],{"class":219},"getMimeTypeFromExtension",[75,934,935],{"class":181},"(extension), ",[75,937,938],{"class":238},"\"UTF-8\"",[75,940,941],{"class":181},", file.",[75,943,944],{"class":219},"inputStream",[75,946,947],{"class":181},"())\n",[75,949,951,954,957,960,963],{"class":77,"line":950},53,[75,952,953],{"class":181},"                } ",[75,955,956],{"class":81},"catch",[75,958,959],{"class":181}," (ex: ",[75,961,962],{"class":85},"Exception",[75,964,590],{"class":181},[75,966,968,971,973],{"class":77,"line":967},54,[75,969,970],{"class":181},"                    assetLoader.",[75,972,46],{"class":219},[75,974,975],{"class":181},"(url)\n",[75,977,979],{"class":77,"line":978},55,[75,980,981],{"class":181},"                }\n",[75,983,985,988,991],{"class":77,"line":984},56,[75,986,987],{"class":181},"            } ",[75,989,990],{"class":294},"else",[75,992,288],{"class":181},[75,994,996,999,1002,1004,1007,1009],{"class":77,"line":995},57,[75,997,998],{"class":81},"                val",[75,1000,1001],{"class":181}," response ",[75,1003,474],{"class":81},[75,1005,1006],{"class":181}," assetLoader.",[75,1008,46],{"class":219},[75,1010,975],{"class":181},[75,1012,1014,1017,1020,1023,1025,1028,1030,1032,1035,1038,1040,1042,1046],{"class":77,"line":1013},58,[75,1015,1016],{"class":294},"                if",[75,1018,1019],{"class":181}," (url.path?.",[75,1021,1022],{"class":219},"endsWith",[75,1024,235],{"class":181},[75,1026,1027],{"class":238},"\".js\"",[75,1029,507],{"class":181},[75,1031,768],{"class":81},[75,1033,1034],{"class":405}," true",[75,1036,1037],{"class":81}," &&",[75,1039,1001],{"class":181},[75,1041,853],{"class":81},[75,1043,1045],{"class":1044},"s39Yj"," null",[75,1047,590],{"class":181},[75,1049,1051,1054,1056],{"class":77,"line":1050},59,[75,1052,1053],{"class":181},"                    response.mimeType ",[75,1055,474],{"class":81},[75,1057,1058],{"class":238}," \"text\u002Fjavascript\"\n",[75,1060,1062],{"class":77,"line":1061},60,[75,1063,981],{"class":181},[75,1065,1067],{"class":77,"line":1066},61,[75,1068,1069],{"class":181},"                response\n",[75,1071,1073],{"class":77,"line":1072},62,[75,1074,1075],{"class":181},"            }\n",[75,1077,1079],{"class":77,"line":1078},63,[75,1080,1081],{"class":181},"        }\n",[75,1083,1085],{"class":77,"line":1084},64,[75,1086,363],{"class":181},[75,1088,1090],{"class":77,"line":1089},65,[75,1091,169],{"emptyLinePlaceholder":168},[75,1093,1095,1097,1099,1102,1104,1106,1109,1112,1115,1118],{"class":77,"line":1094},66,[75,1096,374],{"class":200},[75,1098,271],{"class":81},[75,1100,1101],{"class":219}," onReceivedSslError",[75,1103,382],{"class":181},[75,1105,385],{"class":85},[75,1107,1108],{"class":181},"?, handler: ",[75,1110,1111],{"class":85},"SslErrorHandler",[75,1113,1114],{"class":181},"?, error: ",[75,1116,1117],{"class":85},"SslError",[75,1119,1120],{"class":181},"?) {\n",[75,1122,1124,1127,1130],{"class":77,"line":1123},67,[75,1125,1126],{"class":181},"        handler?.",[75,1128,1129],{"class":219},"proceed",[75,1131,223],{"class":181},[75,1133,1135,1138,1141,1144],{"class":77,"line":1134},68,[75,1136,1137],{"class":1044},"        super",[75,1139,1140],{"class":181},".",[75,1142,1143],{"class":219},"onReceivedSslError",[75,1145,1146],{"class":181},"(view, handler, error)\n",[75,1148,1150],{"class":77,"line":1149},69,[75,1151,363],{"class":181},[75,1153,1155],{"class":77,"line":1154},70,[75,1156,1157],{"class":181},"}\n",[1159,1160,1161],"style",{},"html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .syTEX, html code.shiki .syTEX{--shiki-light:#FF5370;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sfo-9, html code.shiki .sfo-9{--shiki-light:#90A4AE;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":71,"searchDepth":89,"depth":89,"links":1163},[],null,"png","2020-12-18",false,"md",{},"\u002Fposts\u002F2020\u002Fandroid-webview-picture-cache",{"text":1172,"minutes":1173,"time":1174,"words":1175},"3 min read",2.52,151200,504,{"title":22,"description":29},{"loc":1170},"posts\u002F2020\u002F20201218.android-webview-picture-cache",[1180,1181],"技术","Android","uWP_CIUYC6vbsshGYZ4ykWXKhER8hR9mpP1uhdAGLKI",[1184,1190],{"title":1185,"path":1186,"stem":1187,"date":1188,"description":1189,"children":-1},"基于 GitLab CI 和阿里云 k8s 的持续交付解决方案","\u002Fposts\u002F2020\u002Fdevops-gitlab-ci-aliyun-k8s","posts\u002F2020\u002F20201227.devops-gitlab-ci-aliyun-k8s","2020-12-27","今年对于我个人而言，在 DevOps 上的最大收获，莫过于摸索了这套基于 GitLab CI 和 k8s 的持续交付解决方案，其实原理都很简单，在我去年的方案里又做了改进，实现了基于 git tag 的触发方式，并且把原先的本地打包推镜像改为在 GitLab Runner 上打包推镜像。",{"title":1191,"path":1192,"stem":1193,"date":1194,"description":71,"children":-1},"白香词谱","\u002Fposts\u002F2020\u002Fbaixiang-poems","posts\u002F2020\u002F20201217.baixiang-poems","2020-12-17",1777580274596]