RxJava隨記

大概在8月份左右,在Lead的指導下,新的項目中開始引入RxAndroid,並和RetrofitRetrolambda一塊使用。RxJava的學習曲線陡峭,不容易掌握,當時也考慮到這一點,但是團隊人員少,大家學習能力都很強,所以沒有什麼問題。隨着項目的開發,對RxJava也越來越熟悉,同時也感覺到RxJava的強大。

這段時間也想寫一些關於RxJava的Blog,但是由於自己的懶惰,一直擱淺着,現在想把一些零散的Code記錄下來,也算是一個學習過程。

有一個這樣的需求,App在登錄過以後,下次啓動在閃屏出現時刷新一下token,但是閃屏顯示的時間不能太長(假定不能超過3秒),超時後App需要進入主頁,不能block用戶。也就是說登錄服務不能超過3秒,下面是實現:

登錄接口

public interface UserService {

    @GET("/user/login")
    Observable<LoginResponse> login(@Body LoginRequest request);
}

刷新Token的實現

LoginRequest request = new LoginRequest();
//set user info 
//....

ServiceManager.getService(UserService.class)
        .login(request)
        .compose(applySchedulers())
        .timeout(3, TimeUnit.SENCODES, Schedulers.io())         
        .subscribe(response -> {
            if (SUCCESS == response.getStatusCode()) {
                saveToken(response);
            } 
            gotoMainPage();
        }, error -> {
            if (error instanceof TimeoutException) {
                //to error case
            }
            gotoMainPage();
        });

第一版的實現大概就是這樣,測試時發現一個問題:Login的服務速度太快了,半秒時間都不到,閃屏一閃而過,看不清楚就到主頁了。所以這裏還要限制一下,閃屏至少得顯示1秒,如果Login服務完成了,需要等待一下。可以使用zip操作符完成這個需求:

ServiceManager.getService(UserService.class)
        .login(request)
        .compose(applySchedulers())
        .timeout(3, TimeUnit.SENCODES, Schedulers.io())
        .zipWith(Observable.timer(1, TimeUnit.SECONDS, 
                    Schedulers.io()),
                    (response, aLong) -> response)
        .subscribe(response -> {
            if (SUCCESS == response.getStatusCode()) {
                saveToken(response);
            } 
            gotoMainPage();
        }, error -> {
            if (error instanceof TimeoutException) {
                //to error case
            }
            gotoMainPage();
        });

讓Login服務和等待1秒的方法同時完成再通知Subscriber。這樣閃屏的時間就控制在1-3秒之間了。

如果沒有使用RxJava,使用Java的CutDownLatch或者其他Synchronizer可以實現,不過可能麻煩一點,當然我也沒有試過。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章