2014年3月31日 星期一
4am.tw + parallax scrolling
今天看完盧廣仲演唱會後異常熱血,喝了點小酒開始把之前hackthon的project重新從github checkout下來;這次想幫4am.tw用parallax scrolling的library(skollr)寫了另外一個版本. 資料全部來自於原本的網站(不知是否會有授權問題?);而source code(在這)。BTW因為它架在Heroku所以如果太久沒人用會呈現睡眠的狀態。
目前沒有做到很完美~歡迎大家指教。
2014年3月4日 星期二
Bolts it!
根據前一篇Deferred&Promise的討論後,我們最後選擇了Parse發佈的Bolts。這篇大概介紹一下Bolts的實際應用方式,某些部分比較像是再把官方文件在述說一次,最後再做個總結。
Q. 什麼情況下要用Bolts?
A. 所有會卡UI Thread的事情都要,包含網路存取,檔案讀寫,複雜的運算等等
Sample Code:
Task.callInBackground(new Callable<Result>() {
@Override
public Result call() {
// DO SOMETHING
return result;
}
});
Q. 那跟AsyncTask沒什麼差別呀?
A. 沒錯,但是Bolts可以應付更複雜的情境
情境:從網路抓一份list(約一百筆資料),並將list中的個人照片抓取下來,最後放到local資料夾。
難題:當然可以把所有事情放到一個AsyncTask裡面做完,所以整個Task時間拉很長,比較好的做法是不同的工作需求可以用不同的Executor來執行,而不同的Executor可以用不同的Policy來調整(包括ThreadPool的Size,Timeout的時間等等);而且每個Sub-Task也要擁有不同的fallback或Error Handling。
Sample Code:
Task.callInBackground(new Callable<List<User>>() {
@Override public List<User> call() {
return queryListFromNetwork();
}
}, NETWORK_EXECUTOR)
.onSuccess(Continuation<List<User>, List<Image>>() {
@Override public List<List<Image>> then(Task<List<User>> task) {
List<Image> list = new ArrayList<Image>();
for (User user : task.getResult()) {
list.add(loadImage(user));
}
return list;
}
}, NETWORK_EXECUTOR)
.onSuccess(Continuation<List<Image>, Integer>() {
@Override public Integer then(Task<List< Image >> task) {
int count = 0;
for (Image image : task.getResult()) {
saveToStorage(image);
count ++;
}
return count;
}
}, STORAGE_EXECUTOR)
.continueWith(Continuation<Integer, Void>() {
@Override public void then(Task<Integer> task) {
if (task.isFault()) {
task.getError();
}
if (task.isComplete()) {
// show success message
}
}
}, UI_EXECUTOR);
Q. 那是否支援等待多個Task?
A. 當然,可以使用Task.whenAll()
Sample Code
List<Task> tasks = new ArrayList<Task>();
for (int i = 0 ; i< 100 ; i ++) {
tasks.add(Task.callInBackground(new Callable<Void>() {
@Override public void call() {
downloadFile();
return null;
}
}));
}
Task.whenAll(tasks).continueWith(Continuation<Void, Void>() {
@Override public void then(Task<Void> task) {
if (task.isFault()) {
task.getError();
}
if (task.isComplete()) {
// show success message
}
}
}, UI_EXECUTOR);
Q 看起來那麼完美,那目前是否有些缺點?
A 當然,畢竟是v1.0.0,目前看到比較缺乏的功能:1. 無法cancel Task。2. 當使用whenAll的時候無法取得所有Sub-Task的Result。
如果還有什麼使用上或者解說上不是那麼清楚的地方請與我聯繫討論。
2014年2月17日 星期一
Kindle Fire's soft-key bar
最近APP要重新上架到Amazon的App Store,在Review時被測出一個Issue;就是在Full-Screen的Activity當置底(BOTTOM|CENTER)的DialogFragment彈出時,會被Kindle Fire的Soft-key Bar給擋住。
原因在於Kindle Fire的Soft-key不是固定占用系統的高度,所以在Full Screen時,如果彈出的Dialog可以支援Back Key來取消的時候,它就會雞婆的把Soft-key用Overlay的方式跳出,就巧妙地擋住部分的Dialog。
原本的解法是判斷手機是否為Kindle Fire,然後決定要不要加上一個神奇的Margin-Bottom,但後來跟同事Pair-Program後,發現到DialogFragment加道Window時,並沒有繼承現在Activity的屬性(也就是全螢幕),所以才會做出如此蠢事。
最後我們捨棄的Magic Margin,而是強制將DialogFragment設成全螢幕的模式,如此該死的Soft-Key Bar就不會莫名其妙的彈跳出來。
Sample Code :
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
2014年2月9日 星期日
您的Service能夠活多久?
昨晚整理以前信件時,發現某個資料夾裡放滿所有註冊網站服務的認證信,大約都是在2007到2009年所註冊,悲慘的是超過一半的網站都已經GG,以下條列他們以前的服務名稱以及網域。
- http://www.iloveeasy.com/
- CrazyVote
- http://www.pala88.com/
- http://www.bday2all.com/
- 搜股網
- http://www.showgood.tw/
- http://my98.98play.com.tw/
- http://www.badongo.com/
- 地圖日記
- HEMiDEMi
- http://www.ppolis.com
- 意慾蔓延
- joost
- http://www.postreach.com
- http://tw.blogdeco.jp/
- http://www.mybloglog.com/buzz/community/mybloglog/
- http://dob.tnc.edu.tw/
- http://slide.com/
Deferred & Promise
最近同事在解High Resolution issue的時候用到了Deferred/Promise的Design Pattern
問題是這樣子,要同時讀取及輸出N個圖片,但同時可以用M個Worker進行以節省時間,而圖片輸出的順序必須依照z-order排序,這表示圖片B輸出時必須等圖片A輸出完成。
這個問題的關鍵在於Task之間必須有Dependency的觀念,如果純用JAVA硬幹是可以用Thread Pool再加上Callable/Future實現,但針對這種問題已經有Deferred/Promise的設計概念可以使用。
簡單介紹一下D&P的概念(如上圖所示),如果Task之間有Dependency,甚至是帶入參數必須等前一個Task完成才能決定時,就非常適合使用它。
在jQuery 1.5之後已經有直接內建DeferredObject
http://api.jquery.com/category/deferred-object/
在Go的語言也是
http://golang.org/doc/effective_go.html#defer
Python也有人包library
http://twistedmatrix.com/documents/13.0.0/core/howto/defer.html
Java雖然不是內建但也有人包成library : jDeferred,當然也有Android的support
https://github.com/jdeferred/jdeferred
最近Parse也release一款類似的library : Bolts (iOS/Android supported)
https://github.com/BoltsFramework/
參考鏈結:
What are the differences between deferred promise and future in JS
http://stackoverflow.com/questions/6801283/what-are-the-differences-between-deferred-promise-and-future-in-javascript
2013年8月17日 星期六
About Library Dependency Manager on Android Project
開發專案過程中,管理library(不論是3rd party或自製)的問題常常存在,在JAVA的世界可以用ivy、maven或Gradle(有些也包含build script的功能),而在Objective-c可以用CocoPads。
但最近聽到蠻多人用git的submodlue來管理,連sublime text及vim的plugin都用這招管;就Android開發而言,用Maven及Ivy體系就有點綁手綁腳,因為並不是每個library都會放到repository server(除非你想自己host一個,並且手動up-to-date)。
而git的submodlue可能會比較合適,畢竟比較好用的library大部分在Github上都有維護,例如:AndroidQuery、PullToRefresh及ActiveAndroid等等。唯一的缺點大概是每次都要自己compile library project,時間會拉的有點長;不過ADT更新到r17時有改變link library project的policy(如下段文章所示),以後R.java及resource都不會bind到library的jar檔,這大概宣示非自己compile source code不可。
至於Gradle可以多一些期盼(自己還沒有很認真在玩,但groovy語法我是很熟悉),連web framework: Grails也預計在3.0版(最近在2.3 release)後使用它!
但最近聽到蠻多人用git的submodlue來管理,連sublime text及vim的plugin都用這招管;就Android開發而言,用Maven及Ivy體系就有點綁手綁腳,因為並不是每個library都會放到repository server(除非你想自己host一個,並且手動up-to-date)。
而git的submodlue可能會比較合適,畢竟比較好用的library大部分在Github上都有維護,例如:AndroidQuery、PullToRefresh及ActiveAndroid等等。唯一的缺點大概是每次都要自己compile library project,時間會拉的有點長;不過ADT更新到r17時有改變link library project的policy(如下段文章所示),以後R.java及resource都不會bind到library的jar檔,這大概宣示非自己compile source code不可。
Important: If you are still referencing jar libraries manually instead of putting them under libs/ be aware of the following:
- If the project is a Library project, these jar libraries will not be automatically visible to application projects. You should really move these to libs/
- If the project is an application, this can work but you must make sure to mark the jar files as exported.
至於Gradle可以多一些期盼(自己還沒有很認真在玩,但groovy語法我是很熟悉),連web framework: Grails也預計在3.0版(最近在2.3 release)後使用它!
2013年5月26日 星期日
The Free Translate API from Google
The google translate api is not free in v2. but some way(hack) let it's work. we can sniff the Google Translate. and mimic the request, the example show as follow:
main.py
The most trick is the response JSON is invalid. we should remove the wied tag : ",,".
hope it's help for you :)
main.py
TRANSLATE_URL_PREFIX='http://translate.google.com.tw/translate_a/t?client=t&hl=zh-TW&sl=en&tl=zh-TW&ie=UTF-8&oe=UTF-8&multires=1&prev=enter&ssel=0&tsel=0&sc=1&q='
# the user agent is neccerry ... query = "THE WORDS YOU WANT TO TRANSLATE" user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36' headers = { 'User-Agent' : user_agent } req = urllib2.Request(self.TRANSLATE_URL_PREFIX+query), None, headers) res = urllib2.urlopen(req)
r = res.read()
while ',,' in r:
r = r.replace(',,',',')
content = json.loads(r)
result = content[0][0][0])
The most trick is the response JSON is invalid. we should remove the wied tag : ",,".
hope it's help for you :)
訂閱:
文章 (Atom)
