Android 混合开发中加载本地资源那点事
Posted QXXXD
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 混合开发中加载本地资源那点事相关的知识,希望对你有一定的参考价值。
周末跟许久未见的老王(前同事)约了个饭。我临时有事,到那都晚上9点了,很是惭愧。席间聊到公司在做“套壳”App,问我如何加载自定义自体。为了弥补自己的迟到,在整理 demo 时,顺便记录下这个过程。
刚好我最近在公司负责自研小程序框架的重构,所以这事简单啊,就调一个API。便答应回家把关键字发给他。
// android加载自定义字体
// 1. 配置WebViewClient
webView.setWebViewClient(webViewClient);
// 2. 拦截请求
webViewClient.shouldInterceptRequest()
其核心思想就是:拦截。
一、原理
由webView加载一个页面(loadUrl),如果被加载的html放在 assets 目录下,那么使用 file:///android_asset/xxx.html
形式加载,如果是远端地址,则按浏览器加载网页逻辑填写url即可。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1tS0W1YC-1654867998510)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/beb5a2389ba14c1dbba3d63778e37bce~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)] 对于加载本地资源这种情况,我们要在发出的请求,离开App之前,给它拦下来。比如:要加载本地字体,那就要识别这次请求,在 shouldInterceptRequest
中根据约定规则,去本地找字体资源,并构建出请求的响应体,也就是上图中的 response。
二、实战
2.1 前端代码
首先看下前端代码:
index.html
<div class="app">
<div>hello world</div>
<div>新年快乐</div>
<img src="https://img.tukuppt.com/bg_grid/01/03/50/Ljquu0ZtJN.jpg!/fh/350" alt="">
</div>
外层 div 设置 class选择器为 app,app内并排3个元素。这里关键在css:
<style>
@font-face
font-family: HuaGuangGangTieZhiHei;
src: url('http://font/HuaGuangGangTieZhiHei-KeBianTi-2.ttf');
.app
font: 63px HuaGuangGangTieZhiHei;
</style>
这里使用 src 从服务器加载自定义字体。在类选择器 app 中使用该字体。注意这里的 http://font 并非真实的url,仅为了方便我们拦截该请求。
PS:字体的自定义url为 http://font,如果要加载本地图片,可以设置为 http://image,当然也可以统一host,这个根据自己的业务设定即可。
2.2 Android 端代码
-
在布局文件中增加 WebView,这个简单,不贴代码了。
-
设置 WebViewClient ,并重写 shouldInterceptRequest
webView.setWebViewClient(new WebViewClient() @Nullable @Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) Uri url = request.getUrl(); Log.e("MainActivity", "shouldInterceptRequest " + url.toString()); if (customFont && url.toString().contains("font")) // 1 try InputStream inputStream = getAssets().open("HuaGuangGangTieZhiHei-KeBianTi-2.ttf"); // 2 Map<String, String> responseHeaders = new HashMap<String, String>(); responseHeaders.put("Access-Control-Allow-Origin", "*"); return new WebResourceResponse("font/ttf", "utf-8", 200, "ok", responseHeaders, inputStream); // 3 catch (IOException e) e.printStackTrace(); return super.shouldInterceptRequest(view, request); );
- 拦截 url 中包含 font 关键字的请求
- 打开 assets 中的字体
- 构造响应体 WebResourceResponse
-
加载url
webView.loadUrl("file:///android_asset/index.html");
三、后续
今天周一,老王问我调哪个方法,我便给它两个方法: 过一会,他把 MainActivity.java 发给我了,核心代码如下:
wb.loadUrl("http://localhost/web");
wb.setWebViewClient(new WebViewClient()
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
view.loadUrl(String.valueOf(request.getUrl()));
return true;
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
view.loadUrl(url);
return true;
@Override
public void onPageFinished(WebView view, String url)
if (!wb.getSettings().getLoadsImagesAutomatically())
wb.getSettings().setLoadsImagesAutomatically(true);
);
对比实战部分,这段代码是无法加载自定义字体的。虽然重写了 shouldOverrideUrlLoading 方法,但并没有加载 Android 端字体。
四、总结
把远程常用资源放到本地加载,是解决 h5 白屏的关键部分。不管是套壳App,还是 hybrid App,它是个系统工程。想要开发出一套完整可用的框架,需要前端到Android端的知识,尤其是网络请求,这是绕不开的。
以上是关于Android 混合开发中加载本地资源那点事的主要内容,如果未能解决你的问题,请参考以下文章