想用rxjava+rxandroid 替換handle實現數字時鐘,出現無響應,不能隔一秒調用onNext

package com.example.testrxandroid;

import rx.Observable;
import rx.Observable.OnSubscribe;
import rx.android.schedulers.AndroidSchedulers;
import rx.Scheduler;
import rx.Subscriber;
import rx.schedulers.Schedulers;
import android.support.v7.app.ActionBarActivity;
import android.text.format.DateFormat;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity {
TextView textView;
Button button;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    textView = (TextView) findViewById(R.id.textView1);
    button = (Button) findViewById(R.id.button1);

    final Observable<String> observable = Observable
            .create(new OnSubscribe<String>() {

                @Override
                public void call(Subscriber<? super String> subscriber) {
                    // TODO Auto-generated method stub

                    while (true) {//循環
                        try {
                            Thread.sleep(1000);//隔1s
                            subscriber.onNext(DateFormat.format(
                                    "yyyy年MM月dd日 hh:mm:ss",
                                    System.currentTimeMillis()).toString());//返回當前時間
                            subscriber.onCompleted();
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }

                    }
                }
            }).observeOn(Schedulers.newThread())       //計時放在子線程
            .subscribeOn(AndroidSchedulers.mainThread());//界面UI放在主線程

    final Subscriber<String> subscriber = new Subscriber<String>() {

        @Override
        public void onCompleted() {
            // TODO Auto-generated method stub

        }

        @Override
        public void onError(Throwable throwable) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onNext(String str) {
            // TODO Auto-generated method stub
            Log.d("lihui", "time---" + str);
            textView.setText(str);
        }
    };

    button.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            observable.subscribe(subscriber);
        }

    });
}

}
問題:
發現界面點擊button 直接無響應了。
難道rxandroid不能循環調用onnext???

分析log發現線程阻塞,導致無響應。
代碼涉及到線程的地方只有2處:
observeOn(Schedulers.newThread())
subscribeOn(AndroidSchedulers.mainThread() );
一定是這裏出了問題。

網上查到observeOn是對應call()方法,
耗時操作,所以是
Schedulers.newThread();
subsubscribeOn對應onNext(),
所以是主線程 ,更新UI界面。

誤人子弟啊!!!其實正常相反!!!!!
 .subscribeOn(Schedulers.io())  //指定 subscribe() 發生在 IO 線程,子線程,對應call()
 .observeOn( AndroidSchedulers.mainThread() )  //指定 Subscriber 的回調發生在主線程,對應onNext()

修改

.observeOn(AndroidSchedulers.mainThread()) 主線程
.subscribeOn(Schedulers.newThread()); new子線程、io線程

發現界面只更新一次!!!
尼瑪,什麼情況???

發現代碼有個
subscriber.onCompleted(); 監聽完成。觀察者循環不再繼續,退出

去掉後,顯示正常!!!ok

使用rxjava+rxandroid 實現了數字時鐘!!!

停止訂閱:
訂閱者定義:
Subscriber subscriber
或者
Observer observer

如果你是使用了observable+Subscriber

1 observable
2 Subscriber
3 observer

注:
Subscriber subscriber;
subscription=observable.subscribe(subscriber);
subscription.unsubscribe();
再次訂閱:
observable.subscribe(subscriber);
尼瑪,發現沒有效果!!!

解決方法是訂閱者使用 Observer observer 來定義
1)subscription = observable.subscribe(observer);
2)subscription.unsubscribe();
再次訂閱
subscription = observable.subscribe(observer);
生效。

也就是說使用了subscriber作爲訂閱者,那麼你取消訂閱後,無法再次訂閱,只能訂閱一次!!!

如果你想取消後可以重複訂閱,使用observer!!!

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