Android freemarker模板引擎应用

什么是freemarker?


在说这个之前我们都知道web和原生控件之争就那么点事。性能,加载速度,流量,数据交互….

如果我用webView加载一个url页面,要先通过网络解析css,解析html代码,然后渲染生成页面

什么是freemarker?简单点就是,事先把上面这个html文件,放到应用中,用的时候只要传入数据就行


freemarker优点和应用


节约流量,加快网页加载速度

比如某些图表功能,用js库实现比较方便,只要事先放入html模板,传入数据就行。大大节省了流量及加载速度

或者事先已经有网页功能的页面,就不需要在制作Android界面了

此功能在IOS上通用,所以只要一个模板,就可以用在IOS和Android上,大大节约开发时间

实现原理


webView加载本地模板引擎流程

main.tpl ——–> main.ftl+数据 ———> main.html ———> webView.load(main.html)

1、导入freemarker库

compile 'org.freemarker:freemarker-gae:2.3.25-incubating'

2、将main.tpl文件放入assets目录下

<!--main.tpl文件-->
<html>
<head>
  <title>Welcome!</title>
</head>
<body>
  <h1>Welcome ${user}!</h1>
  <p>Our latest product:
</body>
</html>

3、根据main.tpl转成main.ftl

private void prepareTemplate() throws IOException {
    //获取app目录  data/data/package/file/
    String destPath = getFilesDir().getAbsolutePath();
    File dir = new File(destPath);
    //判断文件夹是否存在并创建
    if (!dir.exists()) {
        dir.mkdir();
    }
    //需要生成的.ftl模板文件名及路径
    String tempFile = destPath + "/" + "main.ftl";
    if (!(new File(tempFile).exists())) {
        //获取assets中.tpl模板文件
        InputStream is = getResources().getAssets().open("main.tpl");
        //生成.ftl模板文件
        FileOutputStream fos = new FileOutputStream(tempFile);
        byte[] buffer = new byte[7168];
        int count = 0;
        while ((count = is.read(buffer)) > 0) {
            fos.write(buffer, 0, count);
        }
        fos.flush();
        fos.close();
        is.close();
    }
}

4、将 main.ftl和数据 生成main.html文件

private void genHTML(Product object) {
    String destPath = getFilesDir().getAbsolutePath();
    FileWriter out = null;
    //数据源
    Map root = new HashMap();
    root.put("user", "user");	//传入字符串
    //root.put("product", object.url());     //传入对象(会报错)
    try {
        Configuration cfg = new Configuration(new Version(2,3,0));
        cfg.setDefaultEncoding("UTF-8");  
        //设置报错提示
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        //设置报错提示
        cfg.setLogTemplateExceptions(true);
        out = new FileWriter(new File(destPath + "main.html"));
        //设置.ftl模板文件路径
        cfg.setDirectoryForTemplateLoading(new File(destPath));
        //设置template加载的.ftl模板文件名称
        Template temp = cfg.getTemplate("main.ftl");
        //讲数据源和模板生成.html文件
        temp.process(root, out);
        out.flush();
    } catch (MalformedTemplateNameException e) {

    } catch (IOException e) {

    } catch (Exception e){

    }finally {
        try {
            if (out != null)
                out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

5、webView加载main.html

webview.post(new Runnable() {
    @Override
    public void run() {
        String templateDirRoot = getFilesDir().getAbsolutePath();
        String url = "file://" + templateDirRoot + "main.html";
        webview.loadUrl(url);
    }
});

问题注意点


1、为什么要先把mian.tpl转成main.ftl文件,而不直接把mian.ftl文件放到assets中,然后template直接加载main.ftl文件

因为assets中的文件无法直接读取,所以要先把文件放到data/data/package/….再操作

2、突然发现2016年版的freemarker无法传递对象。

比如在main.ftl文件中${model.name}就无法再继续转成main.html,提示如下错误

Unresolved exception class when finding catch block: java.beans.IntrospectionException

官方说可以,但个人测试了无数遍,就是无法编译对象传值

如下方式可以获取到name

//activity.java
User user = new User();
user.setName="张三"
Map map = HashMap();
map.put("name", user.getName());

//main.tpl
<html>
<body>
  ${name}
<body>
<html>

如下方式无法获取到name

//activity.java
User user = new User();
user.setName="张三"
Map map = HashMap();
map.put("user", user);

//main.tpl
<html>
<body>
  ${user.name}
<body>
<html>

总结


最后没发现webView页面加载快多少,可能数据量少。毕竟要对SD卡操作。流量确实省了,也少了java和html直接的数据交互代码。

当然你会用这玩意后,在老板面前就死命的推荐应用中多用html,省下一大笔时间

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值