Android freemarker模板引擎应用
p1qc8r5t
8年前
<p><strong>什么是freemarker?</strong></p> <p>在说这个之前我们都知道web和原生控件之争就那么点事。性能,加载速度,流量,数据交互….</p> <p>如果我用webView加载一个url页面,要先通过网络解析css,解析html代码,然后渲染生成页面</p> <p>什么是freemarker?简单点就是,事先把上面这个html文件,放到应用中,用的时候只要传入数据就行</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/2fd0f0c0d092aad708f73ded58ca7330.png"></p> <p><strong>freemarker优点和应用</strong></p> <p>节约流量,加快网页加载速度</p> <p>比如某些图表功能,用js库实现比较方便,只要事先放入html模板,传入数据就行。大大节省了流量及加载速度</p> <p>或者事先已经有网页功能的页面,就不需要在制作Android界面了</p> <p>此功能在IOS上通用,所以只要一个模板,就可以用在IOS和Android上,大大节约开发时间</p> <p><strong>实现原理</strong></p> <p>webView加载本地模板引擎流程</p> <p>main.tpl ——–> main.ftl+数据 ———> main.html ———> webView.load(main.html)</p> <p>1、导入freemarker库</p> <pre> <code class="language-java">compile 'org.freemarker:freemarker-gae:2.3.25-incubating'</code></pre> <p>2、将main.tpl文件放入assets目录下</p> <pre> <code class="language-java"><!--main.tpl文件--> <html> <head> <title>Welcome!</title> </head> <body> <h1>Welcome ${user}!</h1> <p>Our latest product: </body> </html></code></pre> <p>3、根据main.tpl转成main.ftl</p> <pre> <code class="language-java">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(); } }</code></pre> <p>4、将 main.ftl和数据 生成main.html文件</p> <pre> <code class="language-java">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(); } } }</code></pre> <p>5、webView加载main.html</p> <pre> <code class="language-java">webview.post(new Runnable() { @Override public void run() { String templateDirRoot = getFilesDir().getAbsolutePath(); String url = "file://" + templateDirRoot + "main.html"; webview.loadUrl(url); } });</code></pre> <p><strong>问题注意点</strong></p> <p>1、为什么要先把mian.tpl转成main.ftl文件,而不直接把mian.ftl文件放到assets中,然后template直接加载main.ftl文件</p> <p>因为assets中的文件无法直接读取,所以要先把文件放到data/data/package/….再操作</p> <p>2、突然发现2016年版的freemarker无法传递对象。</p> <p>比如在main.ftl文件中${model.name}就无法再继续转成main.html,提示如下错误</p> <pre> <code class="language-java">Unresolved exception class when finding catch block: java.beans.IntrospectionException</code></pre> <p>官方说可以,但个人测试了无数遍,就是无法编译对象传值</p> <p>如下方式可以获取到name</p> <pre> <code class="language-java">//activity.java User user = new User(); user.setName="张三" Map map = HashMap(); map.put("name", user.getName()); //main.tpl <html> <body> ${name} <body> <html></code></pre> <p>如下方式无法获取到name</p> <pre> <code class="language-java">//activity.java User user = new User(); user.setName="张三" Map map = HashMap(); map.put("user", user); //main.tpl <html> <body> ${user.name} <body> <html></code></pre> <p><strong>总结</strong></p> <p>最后没发现webView页面加载快多少,可能数据量少。毕竟要对SD卡操作。流量确实省了,也少了java和html直接的数据交互代码。</p> <p>当然你会用这玩意后,在老板面前就死命的推荐应用中多用html,省下一大笔时间</p> <p> </p> <p>来自:http://www.androidchina.net/6533.html</p> <p> </p>