网络连接框架

RxJava的使用

2018-06-03  本文已影响30人  进击的大东

RxJava在Android中的使用

首先我们需要了解什么是观察者模式

举例说明,上代码(假如你交了三个女朋友,然后自己有状态更新的时候通知她们)
    //定义一个女朋友接口(观察者)
   public interface Observer {
    public String getName();
    void update(String state);
  }

具体的女朋友实现类,女朋友的名字,接收到新状态输出

     public class GFObserver implements Observer{
      private String name;
      public GFObserver(String name) {
    this.name=name;
      }
      public String getName() {
      return name;
      }
    @Override
    public void update(String state) {
    System.out.println(this.name+"接收到消息,男朋友最新状态"+state);
    }

      }

//定义一个主题状态基类,包含添加删除女朋友,以及通知女朋友你的状态

  import java.util.ArrayList;
  import java.util.List;

    public abstract class Subject {
/**
 * 保存女朋友的集合
 */
private List<Observer> observers=new ArrayList<>();

/**
 * 新交了个女朋友(添加)
 * @param observer
 */
  public void attach(Observer observer) {
    observers.add(observer);
    System.out.println("我新交女朋友了,她名字叫"+observer.getName());
  }

/**
 * 分手了(删除)
 * @param observer
 */
public void dettch(Observer observer ) {
    observers.remove(observer);
    System.out.println("我和"+observer.getName()+"她分手了");
}
/**
 * 通知所有女朋友更新状态
 * @param state
 */
public void notifyObserver(String state) {
    for(Observer observer:observers) {
        observer.update(state);
    }
  }
  }

//实现主题

public class MyStateSubject extends Subject{
  public void change(String state) {
    notifyObserver(state);
  }
}

//main方法调用

    public class ClientMain {
public static void main(String[] args) {
    //女朋友是观察者
    Observer observer=new GFObserver("罗小丽");
    Observer observer2=new GFObserver("赵美丽");
    Observer observer3=new GFObserver("Ammey");
    //你是被观察者,有新状态就通知女朋友
    MyStateSubject subject=new MassageSubject();
    subject.attach(observer);//在android相当于添加监听器
    subject.attach(observer2);
    subject.attach(observer3);
    subject.change("我在大保健");//在android相当于执行点击事件,android按钮点击属于观察者模式
    
    subject.dettch(observer);
    subject.change("泡吧");
}
}
在上面的例子中女朋友是观察者,你是被观察者,我们通过attach订阅关系,通过change来通知观察者状态的更新.以上就是一个简单的观察者模式的例子

观察者模式在rxjava中的解析

RxJavaAPI文档:http://reactivex.io/RxJava/2.x/javadoc/
RXJava WikiHome:https://github.com/ReactiveX/RxJava/wiki

简单使用

1.使用rxJava监听EditText输入变化
      RxTextView.textChanges(mEditSearch).debounce(200, TimeUnit.MILLISECONDS)
            .subscribeOn(AndroidSchedulers.mainThread())//监听变化需要早主线程
            .filter(new Func1<CharSequence, Boolean>() {
                @Override
                public Boolean call(CharSequence charSequence) {
                    //过滤数据
                    return charSequence.toString().trim().length()>0&&charSequence.toString().trim().contains("a");
                }
            })
            //flatMap
            .switchMap(new Func1<CharSequence, Observable<List<String>>>() {//2.0中Func1变成了ObserverbleSource
                @Override
                public Observable<List<String>> call(CharSequence charSequence) {
                    Log.d("SearchResult","flatMap=="+charSequence);
                    //search
                    List<String> list=new ArrayList<>();
                    list.add("abc");
                    list.add("ada");

                    return Observable.just(list);
                }
            })
            .subscribeOn(Schedulers.io())//网络请求在io
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<List<String>>() {//在2.0版本中Action1是Custom
        @Override
        public void call(List<String> strings) {
            Log.d("SearchResult","list="+strings);
        }
    }, new Action1<Throwable>() {
        @Override
        public void call(Throwable throwable) {
            throwable.printStackTrace();
        }
    });
2.使用RxJava监听按钮点击(可以通过函数debounce或throttleFirst来实现防止按钮在短时间内连续点击)
      RxView.clicks(mButton).throttleFirst(1, TimeUnit.SECONDS).subscribe(new Observer<Void>() {
        @Override
        public void onCompleted() {
        }
        @Override
        public void onError(Throwable e) {
        }
        @Override
        public void onNext(Void aVoid) {
            Log.d("Example0Activity","我是按钮点击");
        }
    });
3.使用RxJava实现本地和网络数据合并
          private Observable<List<Course>> getDatasFromLocal(){
    List<Course> list=new ArrayList<>();
    list.add(new Course("1","菜鸟商城"));
    list.add(new Course("2","菜鸟新闻"));
    return Observable.just(list);
}
private Observable<List<Course>> getDatasFromNetWork(){
    //从网络获取数据
    return mApi.getCourses().subscribeOn(Schedulers.io());
}
//点击按钮合并数据
  public void click(View view) {
    Observable.merge(getDatasFromLocal(),getDatasFromNetWork()).subscribe(new Subscriber<List<Course>>() {
        @Override
        public void onCompleted() {
        }
        @Override
        public void onError(Throwable e) {
        }
        @Override
        public void onNext(List<Course> courses) {
            for(Course course:courses){
                Log.d("Example1Activity","course="+course);
            }
        }
    });
}
4.使用RxJava实现发送验证码倒计时
         int count=60;
public void click(View view) {
    Observable.interval(0,1, TimeUnit.SECONDS)
            .take(count+1)//倒计时的1没有就加1
            .map(new Func1<Long, Long>() {
                @Override
                public Long call(Long aLong) {
                    return count-aLong;
                }//让倒计时数值从大到小
            })
            .observeOn(AndroidSchedulers.mainThread())//在主线程更新UI
            .doOnSubscribe(new Action0() {//在倒计时中不能点击
                @Override
                public void call() {
                    mButton.setTextColor(Color.BLACK);
                    mButton.setEnabled(false);
                }
            })
            .subscribe(new Subscriber<Long>() {
        @Override
        public void onCompleted() {
            Log.d("Example2Activity","onCompleted");
            mButton.setEnabled(true);
            mButton.setText("发送验证码");
        }
        @Override
        public void onError(Throwable e) {
            e.printStackTrace();
        }
        @Override
        public void onNext(Long num) {
            Log.d("Example2Activity","onNext"+num);
            mButton.setText("剩余"+num+"秒");
        }
    });
}

使用RxJava封装一个类似Picasso的图片三级缓存加载框架

1.通过思考和查看api我们发现可以用操作符concat来实现三级缓存就近选取,即当缓存没有数据就去网络获取,缓存有数据就读取缓存数据.

//从磁盘获取数据

      private Observable<String> getDiskObservable(){
    return Observable.create(new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("disk");//当此处为空时就去网络获取
            subscriber.onCompleted();
        }
    });
}

//从网络获取数据

private Observable<String> getNetWorkObservable(){
    return Observable.create(new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("network");
            subscriber.onCompleted();
        }
    });
}

//点击按钮实现从三级缓存获取数据

      //首先获取到缓存和网络的数据对象
    final Observable<String> memoryObservable = getMemoryObservable();
    final Observable<String> diskObservable = getDiskObservable();
    final Observable<String> netWorkObservable = getNetWorkObservable();
    RxView.clicks(mButton).subscribe(new Action1<Void>() {
        @Override
        public void call(Void aVoid){Observable.concat(memoryObservable,diskObservable,netWorkObservable)
                .first(new Func1<String, Boolean>() {
                        @Override
                        public Boolean call(String s) {
                            return !TextUtils.isEmpty(s);
                      }
                    })//只取第一条,判断当前所获取是否为空,是空就去上级数据源获取数据
                    .subscribe(new Action1<String>() {
                        @Override
                        public void call(String s) {//日期输出你是从哪里获取的数据
                            Log.d("activity_example3","get data from--"+s);
                        }
                    });
        }
    });
2.查看Picasso是如何通过链式思想来封装的,把用RxJava处理三级缓存的代码块封装到框架中,通过一个图片加载的创造器来实现图片的加载和缓存并对外提供调用,链式编程思想最后封装并调用测试封装成果.
  public class Image {
  private String url;//图片地址
  private Bitmap bitmap;//图片对象
   
public Image(String url, Bitmap bitmap) {
    this.url = url;
    this.bitmap = bitmap;
}

public String getUrl() {
    return url;
}

public void setUrl(String url) {
    this.url = url;
}

public Bitmap getBitmap() {
    return bitmap;
}

public void setBitmap(Bitmap bitmap) {
    this.bitmap = bitmap;
}
}
         RxView.clicks(mButton).subscribe(new Action1<Void>() {
        @Override
        public void call(Void aVoid) {
            RxImageLoader.with(Example3Activity.this).load("https://www.baidu.com/img/bd_logo1.png?where=super").into(iv);                      
        }
    });
上一篇 下一篇

猜你喜欢

热点阅读