RxAndroid是基于观察者模式的框架,它能漂亮的解决Android的异步问题,具体的用法可参见以下地址。
Android框架:https://github.com/ReactiveX/RxAndroid
其他扩展框架:https://github.com/ReactiveX
ReactiveX官网:http://reactivex.io/
本文通过开启写入缓存和读缓存线程,两步实现水平滑动条实时变化,不需要自定义Handler、Thread、AsyncTask。
1、RxAndroid的配置
在build.gradle(Module:app)中的dependencies中导入下面两个包(RxAndroid的最新版本号可参见RxAndroid的官网)。
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'io.reactivex.rxjava2:rxjava:2.2.4'
2、XML布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".RxAndroidActivity">
<Button
android:id="@+id/start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="开始"/>
<Button
android:id="@+id/stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="停止"/>
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="match_parent"
android:layout_height="20dp"
android:max="100"
style="?android:attr/progressBarStyleHorizontal"
android:progressDrawable="@drawable/progress_bar"/>
</LinearLayout>
3、XML动画文件(progress_bar.xml)
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape>
<corners android:radius="80dp" />
<solid android:color="#FF0000"/>
<stroke android:color="#00FF00"/>
</shape>
</item>
<item>
<scale android:scaleWidth="100%">
<shape>
<solid android:color="#00FF00" />
<corners android:radius="80dp"/>
</shape>
</scale>
</item>
</layer-list>
4、java文件
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import java.util.concurrent.ArrayBlockingQueue;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
public class RxAndroidActivity extends AppCompatActivity {
private Button start = null;
private Button stop = null;
private ProgressBar progressBar = null;
private ArrayBlockingQueue<Integer> dataPool = new ArrayBlockingQueue<Integer>(100);
private volatile boolean exit = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rx_android);
// Initial the data
this.initWidgets();
this.addEventForWidgets();
}
// Initial the widget
private void initWidgets(){
this.start = this.findViewById(R.id.start);
this.stop = this.findViewById(R.id.stop);
this.progressBar = this.findViewById(R.id.progress_bar);
}
// Add Event
private void addEventForWidgets(){
this.start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
exit = true;
writeDataPool();
readDataPool();
}
});
this.stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
exit = false;
}
});
}
// Write to data pool
private void writeDataPool(){
Observable<Integer> observableWriter = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
while (exit){
// Generate the data
emitter.onNext((int)(Math.random()*100));
Thread.sleep((int) (Math.random()*(2000-500)+500));
}
// Submit data
emitter.onComplete();
}
// Set the main thread
}).subscribeOn(Schedulers.newThread());
Observer<Integer> observerWrite = new Observer<Integer>(){
@Override
public void onSubscribe(Disposable d) {
Log.d("observableWriter","Start");
}
@Override
public void onNext(Integer integer) {
// Add the data, write the data pool
dataPool.offer(integer);
}
@Override
public void onError(Throwable e) {
Log.d("observableWriter","error");
}
@Override
public void onComplete() {
Log.d("observableWriter","Complete");
}
};
// Start observable
observableWriter.observeOn(AndroidSchedulers.mainThread()).
subscribe(observerWrite);
}
// Write to data pool
private void readDataPool(){
Observable<Integer> observableRead = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
while (exit){
Log.d("------",dataPool.size()+"");
if(dataPool.size()>0){
emitter.onNext(dataPool.poll());
}
Thread.sleep(1000);
}
// Submit data
emitter.onComplete();
}
// Set the main thread
}).subscribeOn(Schedulers.newThread());
Observer<Integer> observerRead = new Observer<Integer>(){
@Override
public void onSubscribe(Disposable d) {
Log.d("observerRead","Start");
}
@Override
public void onNext(Integer integer) {
// Show the data in the progress bar
progressBar.setProgress(integer);
}
@Override
public void onError(Throwable e) {
Log.d("observerRead","error");
}
@Override
public void onComplete() {
Log.d("observerRead","Complete");
}
};
// Start observable
observableRead.observeOn(AndroidSchedulers.mainThread()).
subscribe(observerRead);
}
}