【原文】http://erinylin.blogspot.com/2011/11/some-tips-to-avoid-leaking-memory-in.html (需要FQ)
Titanium Mobile 真的是一個易學的跨平台 Mobile App SDK,不過由於 Javascript 的自由撰寫風格,外加一般使用者並不了解 Titanium Mobile SDK 倒底中介了什麼,往往開發到後期發現 App 在 runtime 時常出現 out of memory issue,用盡了各種方法「抓漏」也搞不懂為什麼 ?這個時候你就會開始沮喪,然後內心的 OS 狂叫著:「為什麼我不乖乖的學 Objective-C or Java!!!!!」
其實只要堅持幾種撰寫原則,就可以將記憶體漏失傷害降到最低。
以下是幾個簡單用來避免記憶體漏失的技巧:
1. 使用 namespace 來寫作避免混亂 global scope
//專案名稱的 namespace var Ns = {}; //處理 ui Ns.ui = {}; //處理 model Ns.model = {}; //處理 control Ns.control = {};
2. Using factory method to create instance.
使用工廠方法製作實體
Ns.ui.createMainWindow = function(){ var win = Ti.UI.createWindow({ title: 'Hello world' }); //其他要放置在 main window 的 view components 都寫在這邊 //記得回傳實體 return win; } var mainWin = Ns.ui.createMainWindow(); mainWin.open();
3. 小心使用 Ti.App.addEventListener 等 Ti 系列的 global event listener (最強兇手)
如下範例:
Ns.ui.createTestWindow = function(){ var win = Ti.UI.createWindow({ title:'Test' }); var label = Ti.UI.createLabel({ text:'hahaha' }); win.add( label ); //如果監聽客製 event views:hoho 順便將 label 引入 Ti.App.addEventListener('views:hoho', function(){ //label 是 local variable 喔!!!! label.text = 'hohoho'; }); /* * 重點!! 當 global event listener 接受了 local variable 時, * 就請記得在 win.close() 的時候也要一併移除 event listener */ return win; }
4. 無腦的最終手段!!真的找不到哪邊漏水的話視窗關閉時請直接將所有實體關閉或指定 null
Ns.ui.createMainWindow = function(){ var win = Ti.UI.createWindow({ title: 'Hello world' }); var label = Ti.UI.createLabel({ text:'hahaha' }); win.add( label ); //自定 win close 要另外執行的 function win.addEventListener('close', function(){ win.removeEventListener( 'close', arguments.callee ); win.remove( label ); label = null; //再 close 一次也不會出事 win.close(); win = null; }); return win; }
TC
的手机按照不同区域,内置不同的CID,在刷入Recovery和官方RUU升级包的时候难验证CID是否合法,而制作金卡能绕过CID验证。
金卡是一种写入了销售区域标识(用htc的密钥和cid加密)的microSD卡
cid
有两个意思
一个是 SD Card Serial,是 sd卡的密钥。 Sd卡会有,实际上手机内置存储也有,所以带有 sd卡的手机能找到两个 cid。
另一个就是 CountryID,国家 ID,或区域 ID
本文默认 cid是指 SD CardSerial
个人猜测:
Htc把区域 id用 cid加密后写入手机内置存储空间中,我们制作金卡能成功可能是手机内置存储或 sd卡只要有一个信息正确就能通过区域验证,而这个区域 id可能也是通用的,任何区域都能通过。这个区域 id是经过 htc的密钥和 cid双重加密的,所以我们仍然无法自己写入区域 id,而一个逆向工程小组( http://psas.revskills.de/)破解了 htc的密钥(怎么破解的就不知道了),再加上 cid就能写入自己的区域 id了,也就是制作金卡。
1, 获取 sd卡的 cid
下载安装 http://revskills.de/downloads/revskills.zip,该软件可以读取 cid,生成区域 id的密文,但是无注册版只能读取 cid。
打开手机的调试模式(设置 ->应用程序 ->开发 ->USB调试),用 usb线把手机连到电脑上,打开 revskills,选择 Menu->HardwareForensics->Android->ADB Shell Console
在 Get CID按钮右边的下拉框中选择 sd卡(包括手机内置存储)的序号,然后点击 Get CID在下面就会显卡对应的 cid了,我的 sd卡序号是 2,内置存储是 0,要确定哪个是 sd卡,可以把 sd卡拔出,消失的那个就是了。
把 cid复制出来,不要复制空格
2, 生成区域 id的签名
用 revskills也可以,不过需要付费,不过有一个在线的免费方法
打开 http://hexrev.soaa.me/,提交从 revskills中得到的 CID进行转换
打开 http://psas.revskills.de/?q=goldcard,输入你的 email地址和上面转换后的 cid,然后点击 GenerateGoldcard,过一会儿会把 goldcard.img发到你邮箱里,这就是包含签名的文件。
3, 向 sd卡中写入 goldcard.img
在 http://mh-nexus.de/en/downloads.php?product=HxD,下载安装 HxD,或者用其它的十六进制编辑器如 winhex.
用手机以磁盘模式连接电脑或用读卡器把 sd卡插入电脑。
用 HxD打开 goldcard.img, Ctl+A再 Ctl+C,全选复制,然后选择附加 ->打开磁盘 ,选择你的 sd卡(选择的是硬件不是分区,不要选错了),把“以只读模式打开”前的勾去掉,弹出警告窗口时点确定。
用鼠标选择偏移 0h到 170h的行
然选择编辑 ->覆盖式粘贴,或 Ctl+B
然后保存
你的 sd卡就是金卡了
附 Get CID界面和 revskills生成 goldcard.img的界面
在应用中插入广告,很普遍,但是要想在使用Titanium开发的应用中导入广告,去很少。主要是Titanium自身没有提供创建广告View的API。所以需要扩展Titanium,导入额外的Module来实现。
iPhone :
Ti.Admob by Appcelerator
这里是Titanium官方公开的Module。
(1)安装Module
下载下来的Zip文件解压后,里边有3个Module。
进入到AdMob文件夹中
先把其中的ti.admob-iphone-1.0.zip解压,然后把ti.admob文件夹移动到/Library/Application Support/Titanium/modules/iphone中,以后的所有Titanium应用都可以调用到该Module。(如果想只是在自己的Project中导入该Module的话,那么需要把该ti.admob文件夹移动Project下的“modules\iphone\ti.admob ”)
官方Guide:Configuring Apps to Use Modules
(2)设定tiapp.xml,导入Admob的module。
<modules> <module version="1.0">ti.admob</module> </modules>
注意版本号要跟ti.admob文件夹下的子文件夹名相同。
(3)创建View显示广告
在Module的example文件夹中有使用的例子,
var window = Ti.UI.createWindow({ backgroundColor:'#444' }); Titanium.Admob = require('ti.admob'); var adview = Titanium.Admob.createView({ top:0, left:0, right:0, testing:true, adBackgroundColor:'black', primaryTextColor:'blue', secondaryTextColor:'green', publisherId:'<<<YOUR PUBLISHER ID HERE>>>' }); window.add(adview); var label = Titanium.UI.createLabel({ text:'Play around with the ad!', bottom:40, height:'auto', width:'auto' }); window.add(label); window.open();
需要特别注意的是导入其他Module的时候需要使用require。
然后把<<<YOUR PUBLISHER ID HERE>>>替换成自己申请的publisherID后即可。
Android:
Titanium-Android-AdMob-Module
导入方法和iPhone版一样。