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