想用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!!!