Posted in January 2010

Ruby method cache

场景是这样的:我写的手机客户端要从豆瓣上取出当天最受欢迎的书评和影评,这些数据我是到douban.com相关页面上抓取的,大概有20条数据;然后我在这20条数据中随机取出6条显示到手机客户端

Rails内置几种cache机制:1.Page Cache – Fastest, 2.Action Cache – Next Fastest, 3.Fragment Cache – Least Fastest, 4.ActiveRecord Cache – Only available in Edge Rails 。从前端到后端,这几种cache机制粒度都不同,但是都不能满足我的需求。page cache会使每次返回同样的页面,这样达不到“随机”的效果。我希望是这样的:

def get_pop_list
  fetch_reviews.random
  render...
end

def fetch_reviews
  {1...20}
end

我只希望get_reviews这个方法返回的结果是cache的,Action cache好像符合,实验一番后无果,这里的action是指rails中的controller而不是一般的method。

google了下找到了这里,刚好满足我的需求:对method的cache。参考这里例 子:

require 'caches.rb'
  class Spider extend Caches
	def self.fetch_reviews
        	puts "---fetch_reviews"
	        Time.now
	end

	class_caches :fetch_reviews, :timeout => 10.minutes
  end

这里只是一个测试的类,当我们调用Spider.fetch_reviews时,得到的时间每次都是一样的,10分钟后值会刷新,有了timeout我也不用写cron程序来刷新cache了。这个method cache可以对参数cache:不同的参数值会有不同的cache,这个倒是很方便,因为这是一个静态方法,不可避免的要传参数。这点和Page Cache的分页处理倒类似。一个要注意的是在development模式下,controller用load “spider”或者不显示引用(默认为load)不能达到cache的测试效果。

用Java的单例模式来完成这个任务也不太难,这里的self.fetch_reviews也是类的静态方法。不同的是ruby的做法让cache更加透明:加上或者去掉class_caches :fetch_reviews即可改变cache模式,客户端代码不用改变。

Tagged ,

修改Android的自带程序:“屏幕锁” - 加上联通标志

我的机器是G1 + 联通WCDMA + Android 1.6 (Donut)。在原来用移动卡的时候,屏幕锁上有运营商(carrier)的标志,换成联通的卡后没有这个标志(可能是sim卡里面信息不全的缘故),光光的很是煞风景。这里说说下我修改的漫长过程。

0.check out 代码

这里要checkout出donut的代码,目前google源上已经有比这个更新的版本2.1,所以不能直接拿来用,否则我想机器启动会有问题,毕竟屏幕锁是系统第一个界面。

repo init -u git://android.git.kernel.org/platform/manifest.git -b donut

如果原来用的是master也没关系,repo sync时不会重新checkout所有的代码,所以会很快。然后进入项目framework/policy/base,运行命令git describe可以查看当前版本,git tag察看所有tag,可以用git checkout donut会只签出当前project的代码(很奇怪,donut这个HEAD不在git tag里面,git水很深啊)

1.修改Java代码。

研究了源代码后,我发现如果用修改配置或者扩展类的方法是改不了这个标志的,因为很多类在初始化时就定义了hard coding了type,扩展已有类是行不通的。于是就直接修改界面代码吧,这样也简单明了。定位framework/policy/base/phone下面的LockScreen.java,

    private void refreshSimOkHeaders(CharSequence plmn, CharSequence spn) {
        final IccCard.State simState = mUpdateMonitor.getSimState();
        if (simState == IccCard.State.READY) {
            if (plmn != null && !TextUtils.isEmpty(plmn)) {
                mHeaderSimOk1.setVisibility(View.VISIBLE);
                mHeaderSimOk1.setText(plmn);
            } else {
                mHeaderSimOk1.setVisibility(View.GONE);
            }

            if (spn != null && !TextUtils.isEmpty(spn)) {
                mHeaderSimOk2.setVisibility(View.VISIBLE);
                mHeaderSimOk2.setText(spn);
            } else {
                //mHeaderSimOk2.setVisibility(View.GONE);
                mHeaderSimOk2.setVisibility(View.VISIBLE);
                mHeaderSimOk2.setText("China Unicom");
            }

最后3行是我修改的,hard coding就没啥好说的了。关于plmn和spn的区别,看这里

2. 编译

make android.policy

这里只编译这个项目,会得到一个android.policy.jar。

遇到‘convert_endian’ undeclared (first use in this function)的错误看这里,error: cast from ‘char*’ to ‘int’ loses precision的错误看这里。个人感觉新版本代码编译错误更少。

另:我倒是想过直接修改android.policy.jar里面的classes.dex,比如先反编译,修改后直接再编译回去。不过网上找了几个工具,效果都不是很好。不清楚是dex反编译现在不成熟还是Google对dex保护太好。

3.模拟机上测试

为了保险起见(我可就这个手机),现在emulator上运行看看。本来想直接修改sdk带的system.img省事,后来发现用mkyaffs2image生成image不能用:模拟器起不来。算了,后来我是老老实实用make snod重新生成system.img。

4.上传到真机

这又是一个很烦琐的过程:mount /system让它可写(步骤见这里),adb push(先adb pull 备份,保险…),然后,如果你跟我一样遇到Failed to copy: Permission denied.和Cross-device link的问题,一定要参考这个贴子,不要自己折腾了。最后chmod 644 android.policy.jar,恢复文件原来的属性。

5.重启

没啥问题,看来我是太小心了。看到结果后感觉也很一般,这个过程太折腾了,可能会又更好的办法吧,我是对git和make一点不熟,出了问题只能google。还好有点收获…休息去了,我的周末…

device

Tagged ,

模仿Google Reader的豆瓣手机客户端:“煮豆”

一直觉得Google Reader做的不错,Ajax的特则很适合用手机用户:比如bookmark一条记录不用刷新页面,这个对pc来说不是很关键,但是手机网路慢而且不稳定,可能一次刷新页面就再也回不去了,而用户前面一个页面还没有看完,所以“异步”对手机来说很重要。

于是有个这个山寨版的“Google Reader”- zudou.net,也可以说是向Reader致敬吧。主要特征就是“折叠式”的页面显示,我觉得Yahoo UI Pattern应该把这个加入它的库中。

主要功能有:

1)摘取douban主页上面的最受欢迎的书评和影评信息(还没有加上cache功能);

2)显示评论的详细信息,也可以收藏评论的书或电影,暂时还没有回应评论的功能,好像douban API还没有看放这个功能;

3)发表广播和现实友邻广播。

适合的客户端为:Android, iPhone。

zudou1

zudou2

1.15 add: 惊闻Google欲退出中国,痛心!何处为安身立命之所!向Google致敬!

1.15 add: 这个功能为什么不加入到Google Reader中呢?因为我想豆瓣也有“最流行书评”的RSS Feed,当热也可以加到Reader中,不过,Reader的“收藏”功能不能收藏豆瓣的书籍,或者说收藏功能只是在Reader中有效(评论也只能在reader的圈子中交流,这里Reader是一个信息孤岛)。douban API的有点像基于“RSS协议”的API,能否做个reader的插件(假如reader用这个功能),当在reader中操作时,可以反映到各个RSS的源,这样想发表评论也不用到真实页面去发表了?操作性比较差,很多网站都要登录后才能发表评论…

1.16 add:iPhone模拟器上的截屏

zudou-iphone

Tagged

做supporter的苦恼

做supporter,注定对系统不能全面的了解,因为它不是你开发出来的,你可能对某个地方很熟悉,但是想做到管中窥豹,难。

做supporter有点类似黑客,因为要找到问题所在然后解决问题,有时候跟的很深,最后的却修改很少,有时候会采用非常规的手段来让一切运转起来,这里没有设计,看不到代码的美观,只看到一堆的齿轮,一个连着另外一个。

深挖有时候会遇到进退两难:是手中的信息(条件)还不够,这道题无解?还是代码中有自己没有搞明白的地方?是就此收手还是再挖几锹?纠缠。

更苦恼的是当你对某个项目熟悉了之后,大多3个月后,一切感觉很轻车熟路,很有信心,你仿佛看到迷雾中的整个建筑的全貌,正准备欣赏建筑的细节(原来做的事情就如同打洞啊),… 这时候领导又要你去supporter另外一个项目,于是乎又从头来过。