顯示具有 facebook 標籤的文章。 顯示所有文章
顯示具有 facebook 標籤的文章。 顯示所有文章

2015年4月25日 星期六

Fresco : an image management library





    書在F8發表了自己的Image Loader Library(Android)叫做Fresco,因為他們在市面上找不到完全符合需求的Library,所以自己就寫了一個(這邏輯很Facebook),它主要強調功能有五:1)有更佳的記憶體管理、2)支援Progressive JPEG、3)Animation Format(GIF和WebP)、4)Drawing(更整合customize layer:例如想要塞浮水印之類的)以及 5)更加的Loading體驗。

針對第五點想要特別強調:1) 它可以同時設定多種resolution的圖片,讓較低解析度的圖片先秀出、2) 支援EXIF Thumbnail、3) Auto-resize rotation(base on EXIF)、 4) 讓Android 2.3的裝置也支援WebP。

翻了翻它的source code發現,所以decoder都適用NDK寫的,包含jpeg、png、gif跟WebP真的是佛心來著。看來該把原本在用的Ion拔掉了。


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。



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



2013年4月27日 星期六

Facebook : Login for Desktop Apps



   果想要讓一個小盒子(例如:Embedded System or Raspberry Pi)能夠拿到facebook的access token來做一些事情,例如:控制GPIO顯示未讀訊息(NOTICE : Physical Facebook Notifier)、抓臉書的相片當做數位像框、當關注的異性感情狀態變更時會有鬧鈴提醒等等。

   盒子通常不會有實體IP(而且也不切實際,就算有IP,幫每個盒子都必須申請一個特別的Facebook ID也很噁心),此時就可以使用Desktop版本的登入方式,操作概念如下:

1. 將redirect_url改成 https://www.facebook.com/connect/login_success.html

    https://www.facebook.com/dialog/oauth?
        client_id=YOUR_APP_ID
       &redirect_uri=https://www.facebook.com/connect/login_success.html
       &scope=COMMA_SEPARATED_LIST_OF_PERMISSION_NAMES
       &response_type=token


2. 偵測redirect的event,在把redirect Url上的access token變數拿下來用

https://www.facebook.com/connect/login_success.html#
    access_token=USER_ACCESS_TOKEN...

   偵測的方式可以用WebView掛Listener來完成,看起來還是要提供螢幕讓使用者登入:(,不過之前在hack Google Play Console的API時,有參考Andlytics模仿Google登入的request內容,應該還是有機會辦到純Program的方式拿到access token


----------- 2013/4/29 修正 -------------

看起來NOTICE : Physical Facebook Notifier作法比較簡單,只把七段顯示器直接透過serial port來操作,所有認證的畫面及流程都用桌面軟體搞定。