【年度最干干货】: 明星框架:把app代码写在远程服务器上。
访问量: 2760
认识明星是我2015年做的最有价值的事,之一 ^_^ 。
而明星框架,则是我2015年遇到的最牛逼框架,没有之一。
原理:
把app的代码写到服务器端,然后在app端访问远程界面。 把代码缓存到本地。 使用 eval () 来调用。
这个框架能够实现,在技术上有几种依托:
1. 代码不需要编译。
2. 支持eval 这样的方法
好处是:
1. 不需要编译的等待时间。 这边写了那边立马看到
2. 可以随时随地修改app上的代码。
前景:
这个框架绝对是一种变革
我们把Titanium 看成是 nginx, 则android 就是linux. 我们在linux上写html是不需要编译的, 同理,我写mobile app,骨架部分需要编译, 肌肉部分是不需要的。
过程:
假设你的代码,在titanium上是静态代码:
app.js:nearby_window = requeir('/lib/nearby_houses.js'); window = Ti.UI.createWindow({ title: '本地的工地' }) label = Ti.UI.createLabel({ text: '这里的内容是本地的,将来要放到远程上' }) window.add(label) window.open()
那么,我们要做的是:
1. 先把这个window 在app.js中 抽取出来,成为一个 js module:
app目录下的 /Resources/lib/nearby_houses.js:
Wrapper = function(){ window = Ti.UI.createWindow({ title: '本地的工地' }) label = Ti.UI.createLabel({ text: '这里的内容是本地的,将来要放到远程上' }) window.add(label) return window; } module.exports = Wrapper;
2. 在 Resources/app.js 中,使用 require 来调用这个module:
wrapper = require('lib/nearby_houses.js'); wrapper.open()
运行,没问题~
3. 开始分解 nearby_houses.js, 把它的内容从远程调用:
Wrapper = -> Ti.include '/lib/public.js' window = Ti.UI.createWindow title: '附近的工地' setup_window = -> http_call url: Ti.App.householder_code_url + "/householder_code/nearby_houses.js" cache: true success: (e) -> console.info "== got code successfully" some_window = eval(e.responseText) some_window(window) // 下面部分的代码,是当网络不好时,生成一个消息提示,并且给个按钮,让用户重新下载代码。 error: () -> window.add Ti.UI.createLabel top: __l(100) text: '哎呀,网络连接似乎有点问题!' textAlign: 'center' font: fontSize: __l(18) color: '#333' button = Ti.UI.createButton title: "重试" top: __l(150) width: __l(80) font: fontSize: __l(18) button.addEventListener "click", (e) -> setup_window() window.add(button) setup_window() window module.exports = Wrapper
这个 http_call 的方法看起来这样:( 放到 Resources/lib/public.js 中)
http_call = (options) -> if options.cache if Ti.App.deployType == "production" record = require("/lib/db").db.select_with_check(options.url, 0) unless record.blank if options.success options.success({ responseText: record.json}) xhr = Ti.Network.createHTTPClient() xhr.timeout = Ti.App.timeout xhr.onerror = -> if options.error then options.error this else show_timeout_dlg xhr,url xhr.onload = -> options.success this if options.success url = options.url if options.url.indexOf(Ti.App.householder_host_url) == 0 append = "osname="+Ti.App.osname+"&osversion="+Ti.App.osversion+"&appversion="+Ti.App.version+"&manufacturer="+Ti.App.manufacturer+"&model="+Ti.App.model+"&memory="+Ti.Platform.availableMemory url += if options.url.indexOf("?") > 0 then "&" + append else "?" + append xhr.open options.method || 'GET', url if options.args then xhr.send options.args else xhr.send()
对于 lib/db.coffee :
Bizsim = Bizsim or {} Bizsim.db = {} Bizsim.db.select_with_check = (json_type, id) -> record = Bizsim.db.select_one_json(json_type, id) now = new Date #数据3天过期 if Titanium.Network.online and !record.blank and now.getTime() - (record.created_at) > 1000 * 3600 * 24 * 3 Bizsim.db.delete_one_json json_type, id return { blank: true } record Bizsim.db.delete_one_json = (json_type, id) -> Ti.App.db.execute 'delete from jsons where json_type=? and id=?', json_type, id return module.exports = Bizsim
同时,你要有个远程服务器,在远程服务器的 /code/nearby_houses.js 中,要返回这个内容:
NearbyHousesWindow = function(window) { Ti.include('/lib/public.js'); label = Ti.UI.createLabel({ text: '这个Label被放到了远程服务器上' }) window.add(label); return window; }; module.exports = NearbyHousesWindow;
现在,你要修改window的代码的话,完全不需要编译重启app, 直接在远程修改就完事儿了。
几点注意:
1. 一些module , 不但文件需要放到本地, 代码运行最好也在本地,否则会出现 有时加载不了的情况。 深层原因疑似 网络加载有延迟。 放到本地的话就没有了。
2. 一些方法,需要提前放到一个 匿名js中运行一下。 例如:
$ cat Resources/anon.js /* * 这个文件,系统是不会调用的。 * 它存在的目的,是为了骗过编译器,(先调用一些API, createTextArea, createOptionDialog) * 让编译到实体机时,系统不会出错。 * Anon 的意思是 Anonymouse * */ function AnonWindow(title) { var t = Ti.UI.createTextArea({ hintText: "反馈内容" }); var optionsDialogOpts = { title: "选择您想进行的操作", options : ["1", "2"], cancel : 1 }; Titanium.UI.createOptionDialog(optionsDialogOpts); Ti.Filesystem.applicationCacheDirectory; Titanium.UI.iPhone.TableViewStyle.GROUPED, Ti.Geolocation.preferredProvider = "gps"; } module.exports = AnonWindow;