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。



如果還有什麼使用上或者解說上不是那麼清楚的地方請與我聯繫討論。