框架原理之Glide

1.Glide

注意:因为android默认给每一个应用分配16M的内存,如果加载过多的图片的话,容易出现OOM

(1).glide的基本使用

//加载图片到ImageView,并指定缓存策略
RequestOptions requestOptions = new RequestOptions();
requestOptions.placeholder(loadingResId) //设置“加载中”状态时显示的图片
              .error(errorResId); //设置“加载失败”状态时显示的图片
Glide.with(context)
     .load(url)
     .apply(requestOptions)
     .into(imageView);

//加载图片到ImageView,并指定占位图
RequestOptions requestOptions = new RequestOptions();
requestOptions.placeholder(loadingResId) //设置“加载中”状态时显示的图片
              .error(errorResId); //设置“加载失败”状态时显示的图片
Glide.with(context)
     .load(url)
     .apply(requestOptions)
     .into(imageView);

(2).glide的缓存策略
DiskCacheStrategy.NONE 不缓存文件
DiskCacheStrategy.SOURCE 只缓存原图
DiskCacheStrategy.RESULT 只缓存最终加载的图(默认的缓存策略)
DiskCacheStrategy.ALL 同时缓存原图和结果图

默认的磁盘缓存目录:data/data/包名/cache/image_manager_disk_cache
自定义外部缓存路径:

 builder.setDiskCache(new ExternalCacheDiskCacheFactory(context, "egatee", 100 * 1024 * 1024));

磁盘缓存目录:Android/data/包名/cache/egatee/

(3).glide生命周期源码分析
(3.1).with()方法,如果传入的是ApplicationContext 或者当前线程在子线程中,就创建一个能感知应用生命周期的RequestManager(new ApplicationLifeCycle()). 如果传入的是 Activity或者Fragment且是在主线程中,则会创建一个空白无UI的SupportRequestManagerFragment【Androidx.app.Fragemnt】or RequestManagerFragment【Android.app.Fragemnt】,同时会在Fragment构造方法中,实例化ActivityFragmentLifeCycle【被观察者】 , 在Fragment的生命周期方法中,通过ActivityFragmentLifeCycle调用对应onStart,onStop,onDestory对应的方法,同时也会创建一个对应的RequestManager(current.getGlideLifeCycle()),并把SuportRequestManagerFragment中的ActivityFragmentLifeCycle被观察者实例作为参数传入,然后添加观察者lifecycle.add(this),并且每一个RequestManager都实现了LifeCycleListener观察者接口,所以当Fragment的生命周期发生变化时,
会调用被观察者ActivityFramentLifeCycle中对应的自定义方法onStart(),onStop(),onDestory(),并且遍历实现了LifeCycleListener接口的观察者【RequestManager】列表,调用RequestManager中的onStart(),onSto(),onDestory()方法,最后通过调用RequestTracker中的resumeRequests(), pauseRequest,clearRequest来恢复,暂停,清除所有的请求。

  public static RequestManager with(@NonNull FragmentActivity activity) {
    return getRetriever(activity).get(activity);
  }

  public RequestManager get(@NonNull FragmentActivity activity) {
    if (Util.isOnBackgroundThread()) {
      return getApplicationManager(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      frameWaiter.registerSelf(activity);
      FragmentManager fm = activity.getSupportFragmentManager();
      return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
  } 
 /*创建一个RequestManager,并没有创建空白的Fragment,直接 new ApplicationLifecycle() 被观察者,和应用的生命周期绑定.*/
  private RequestManager getApplicationManager(Context context) {
    if (applicationManager == null) {
      synchronized (this) {
        if (applicationManager == null) {
          Glide glide = Glide.get(context.getApplicationContext());
             applicationManager =new RequestManager(new ApplicationLifecycle());
        }
      }
    }
    return applicationManager;
  }
//【被观察者】实现类 ApplicationLifecycle实现了Lifecycle接口,无自定义onStart(),onStop(),onDestory()方法,不会绑定生命周期.
class ApplicationLifecycle implements Lifecycle {
  @Override
  public void addListener(@NonNull LifecycleListener listener) {
    listener.onStart();
  }
  @Override
  public void removeListener(@NonNull LifecycleListener listener) {
    // Do nothing.
  }
}

  private RequestManager supportFragmentGet( 
       Context context,
      FragmentManager fm,
     Fragment parentHint,
      boolean isParentVisible) {
   //创建空白无UI的Fragment 
    SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint);
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
      Glide glide = Glide.get(context);
     /*current.getGlideLifecycle()把Fragment中的ActivityFragmentLifeCycle被观察者对象传递给
        RequestManager 用来添加观察者 */
       requestManager =new RequestManager( current.getGlideLifecycle());//简化过
          
      if (isParentVisible) {
        requestManager.onStart();
      }
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }

(3.2).观察者接口LifecycleListener,被观察者接口Lifecycle

public interface LifecycleListener {
  void onStart();
  void onStop();
  void onDestroy();
}
public interface Lifecycle {
  void addListener(@NonNull LifecycleListener listener);  //添加观察者
  void removeListener(@NonNull LifecycleListener listener); //移除观察者
}

(3.3). 每一个RequestManager就是一个实现了LifeCycleListener接口的观察者

public class RequestManager implements LifeCycleListener{
  RequestManager(Lifecycle lifecycle) {
     lifecycle.addListener(this); //添加观察者
  } 
  
  synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
    targetTracker.track(target);
    requestTracker.runRequest(request);
  }
   public synchronized void onStart() {
     requestTracker.resumeRequests(); //启动所有请求
      targetTracker.onStart();
   }
 public synchronized void onStop() {
     requestTracker.pauseRequests(); //暂停所有请求
     targetTracker.onStop();
  }
public synchronized void onDestroy() {
    requestTracker.clearRequests(); //移除所有的请求
    lifecycle.removeListener(this); //移除观察者
  
  }
}

(3.4).被观察者实现类ActivityFramentLifeCycle实现了Lifecycle接口,自定义onStart(),onStop(),onDestory()方法.

class ActivityFragmentLifecycle implements Lifecycle {
  private final Set<LifecycleListener> lifecycleListeners =
      Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
   @Override
  public void addListener(LifecycleListener listener) {
     lifecycleListeners.add(listener);
  }
  @Override
  public void removeListener(@NonNull LifecycleListener listener) {
     lifecycleListeners.remove(listener);
  }
//遍历所有实现了LifeCycleListener接口的RequestManager ,调用其中onStart()方法
 void onStart() {
    for (LifecycleListener lifecycleListener : lifecycleListeners) {
      lifecycleListener.onStart();
    }
  }
//遍历所有实现了LifeCycleListener接口的RequestManager ,调用其中onStop()方法
  void onStop() {
    for (LifecycleListener lifecycleListener : lifecycleListeners)) {
      lifecycleListener.onStop();
    }
  }
//遍历所有实现了LifeCycleListener接口的RequestManager ,调用其中onDestroy()方法
  void onDestroy() {
    for (LifecycleListener lifecycleListener : lifecycleListeners) {
      lifecycleListener.onDestroy();
    }
  }
}

(3.5).空白无UI的SupportRequestManagerFragment 或者RequestManagerFragment(观察者模式的调用者)

public class SupportRequestManagerFragment extends Fragment {
     private final ActivityFragmentLifecycle lifecycle;
    public SupportRequestManagerFragment() {
       this.lifecycle=new ActivityFragmentLifecycle());  //构造方法新建一个被观察者对象
   }
  //获取被观察者对象//在创建RequestManager时传递进去。
 ActivityFragmentLifecycle getGlideLifecycle() {
    return lifecycle;
  }
  public void onStart() {
     lifecycle.onStart(); //调用被观察者对象中的onStart()方法
  }
 public void onStop() {
    lifecycle.onStop();//调用被观察者对象中的onStop()方法
 }
 public void onDestroy() {
    lifecycle.onDestroy();//调用被观察者对象中的onDestroy()方法
  }
}

(3.6).RequestTracker 请求跟踪类

public class RequestTracker {
 private final Set<Request> requests =  Collections.newSetFromMap(new WeakHashMap<Request, Boolean>());
  private final List<Request> pendingRequests = new ArrayList<>();

 public void runRequest(@NonNull Request request) { //启动当前请求.
    requests.add(request);
    if (!isPaused) {
      request.begin();
    } else {
      request.clear();
      pendingRequests.add(request);
    }
  }
  public void resumeRequests() {  //启动所有请求
    for (Request request : requests) {
      if (!request.isComplete() && !request.isRunning()) {
        request.begin();
      }
    }
    pendingRequests.clear();
  }
  public void pauseRequests() { //暂停所有的请求
    for (Request request : requests) {
      if (request.isRunning()) {
        request.pause();
        pendingRequests.add(request);
      }
    }
  public void clearRequests() { //清除所有的请求
    for (Request request : requests) {
       requests.remove(request)
    }
    pendingRequests.clear();
  }
}

(4).glide三级缓存机制源码分析

image.png

(4.1).Glide.into()主流程源码分析

 private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> options,
      Executor callbackExecutor) {
     //构建Request请求,实现类是SingleRequest
    Request request = buildRequest(target, targetListener, options, callbackExecutor);  
    requestManager.track(target, request);// 调用RequestTrack中的runRequest()---> request.begin()
    return target;
  }

(4.2).调用SingleRequest中begin()

public void begin() {
 if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
        onSizeReady(overrideWidth, overrideHeight);
      } else {
        target.getSize(this);
      }
}

public void onSizeReady(int width, int height) {

      loadStatus =
          engine.load(
              glideContext,
              model,
              requestOptions.getSignature(),
              this.width,
              this.height,
              requestOptions.getResourceClass(),
              transcodeClass,
              priority,
              requestOptions.getDiskCacheStrategy(),
              requestOptions.getTransformations(),
              requestOptions.isTransformationRequired(),
              requestOptions.isScaleOnlyOrNoTransform(),
              requestOptions.getOptions(),
              requestOptions.isMemoryCacheable(),
              requestOptions.getUseUnlimitedSourceGeneratorsPool(),
              requestOptions.getUseAnimationPool(),
              requestOptions.getOnlyRetrieveFromCache(),
              this,
              callbackExecutor);
    }
  }

(4.2).调用Engine中的load方法

 public <R> LoadStatus load(
      GlideContext glideContext,
      Object model,
      Key signature,
      int width,
      int height,
      Class<?> resourceClass,
      Class<R> transcodeClass,
      Priority priority,
      DiskCacheStrategy diskCacheStrategy,
      Map<Class<?>, Transformation<?>> transformations,
      boolean isTransformationRequired,
      boolean isScaleOnlyOrNoTransform,
      Options options,
      boolean isMemoryCacheable,
      boolean useUnlimitedSourceExecutorPool,
      boolean useAnimationPool,
      boolean onlyRetrieveFromCache,
      ResourceCallback cb,
      Executor callbackExecutor) {
    long startTime = VERBOSE_IS_LOGGABLE ? LogTime.getLogTime() : 0;

    EngineKey key =
        keyFactory.buildKey(
            model,
            signature,
            width,
            height,
            transformations,
            resourceClass,
            transcodeClass,
            options);

    EngineResource<?> memoryResource;
    synchronized (this) {
      memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);

      if (memoryResource == null) {
        return waitForExistingOrStartNewJob(
            glideContext,
            model,
            signature,
            width,
            height,
            resourceClass,
            transcodeClass,
            priority,
            diskCacheStrategy,
            transformations,
            isTransformationRequired,
            isScaleOnlyOrNoTransform,
            options,
            isMemoryCacheable,
            useUnlimitedSourceExecutorPool,
            useAnimationPool,
            onlyRetrieveFromCache,
            cb,
            callbackExecutor,
            key,
            startTime);
      }
    }

    cb.onResourceReady(
        memoryResource, DataSource.MEMORY_CACHE, /* isLoadedFromAlternateCacheKey= */ false);
    return null;
  }
  //从内存中查找缓存
  private EngineResource<?> loadFromMemory(
      EngineKey key, boolean isMemoryCacheable, long startTime) {
    if (!isMemoryCacheable) {
      return null;
    }

    EngineResource<?> active = loadFromActiveResources(key); //从活动资源中查找缓存
    if (active != null) {
      if (VERBOSE_IS_LOGGABLE) {
        logWithTimeAndKey("Loaded resource from active resources", startTime, key);
      }
      return active;
    }

    EngineResource<?> cached = loadFromCache(key);
    if (cached != null) {
      if (VERBOSE_IS_LOGGABLE) {
        logWithTimeAndKey("Loaded resource from cache", startTime, key);
      }
      return cached;
    }
    return null;
  }
  //从活动缓存中找
  private EngineResource<?> loadFromActiveResources(Key key) {
    EngineResource<?> active = activeResources.get(key);
    if (active != null) {
      active.acquire();
    }
    return active;
  }
  synchronized EngineResource<?> get(Key key) {
     Map<Key, ResourceWeakReference> activeEngineResources = new HashMap<>();//弱引用
    ResourceWeakReference activeRef = activeEngineResources.get(key);
    if (activeRef == null) {
      return null;
    }

    EngineResource<?> active = activeRef.get();
    if (active == null) {
      cleanupActiveReference(activeRef);
    }
    return active;
  }
 //从活动缓存中找,实际是从内存缓存中移除,然后添加到活动缓存
private EngineResource<?> loadFromCache(Key key) {
    EngineResource<?> cached = getEngineResourceFromCache(key); //cache
    if (cached != null) {
      cached.acquire();
      activeResources.activate(key, cached);
    }
    return cached;
  }

 //从内存缓存中移除,然后添加到活动缓存
 /*此处的cache是 memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());*/
 private EngineResource<?> getEngineResourceFromCache(Key key) {
    Resource<?> cached = cache.remove(key); 
    final EngineResource<?>   result =
          new EngineResource<>(
              cached, /*isMemoryCacheable=*/ true, /*isRecyclable=*/ true, key, /*listener=*/ this);
    return result;
  }

(4.3).没有内存缓存,就通过EngineJob启动线程池,然后执行DecodeJob中的run()方法

public synchronized void start(DecodeJob<R> decodeJob) {
    this.decodeJob = decodeJob;
    GlideExecutor executor =
        decodeJob.willDecodeFromCache() ? diskCacheExecutor : getActiveSourceExecutor();
    executor.execute(decodeJob);
  }
//执行DecodeJob中的run()方法
 public void run() {
   runWrapped();
}

 private void runWrapped() {
    switch (runReason) {
      case INITIALIZE:
        stage = getNextStage(Stage.INITIALIZE);
        currentGenerator = getNextGenerator(); 
        runGenerators();
        break;
    }
  }

  private DataFetcherGenerator getNextGenerator() {
    switch (stage) {
      case SOURCE:
        return new SourceGenerator(decodeHelper, this);  
    }
  }

  public boolean startNext() {
  
    while (!started && hasNextModelLoader()) {
      loadData = helper.getLoadData().get(loadDataListIndex++);
     //检测磁盘缓存
      if (loadData != null
          && (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
              || helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
        started = true;
        startNextLoad(loadData);
      }
    }
    return started;
  }

(4.4).没有找到DiskCache缓存,就通过HttpUrlFetcher中的HttpURLConnection进行网络请求,返回一个
InputStream输入流,对InputStream进行采样压缩,最终拿到bitmap,然后把bitmap转换成Drawable,
然后构建磁盘缓存DiskCache,构建内存缓存LruResourceCache,然后构建ActivityResource活动缓存,并从活动缓存中取出图片资源,调用ImageViewTarget子类DrawableImageTarget中的onResourceReady()方法展示图片

 public void loadData(Priority priority,DataCallback<? super InputStream> callback) {
    long startTime = LogTime.getLogTime();
    try {
     //返回输入流
      InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
      callback.onDataReady(result);
    } catch (IOException e) {   
      callback.onLoadFailed(e);
    } finally {}
  }

(4.5).ImageViewTarget和DrawableImageViewTarget的调用流程

  public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition) {
    if (transition == null || !transition.transition(resource, this)) {
      setResource(resource); //  protected abstract void setResource(@Nullable Z resource); 抽象方法
    } else {
      maybeUpdateAnimatable(resource);
    }
  }

public class DrawableImageViewTarget extends ImageViewTarget<Drawable> {
  public DrawableImageViewTarget(ImageView view) {
    super(view);
  }
  @SuppressWarnings({"unused", "deprecation"})
  @Deprecated
  public DrawableImageViewTarget(ImageView view, boolean waitForLayout) {
    super(view, waitForLayout);
  }
  @Override
  protected void setResource(@Nullable Drawable resource) {
    view.setImageDrawable(resource);  //显示图片
  }
}

Glide.with()的时候会更具context类型和当前线程,返回一个对应的RequestManager,并创建了一个空白的SupoortRequestManagerFragment来管理生命周期,然后调用load方法,设置加载地址,返回的是一个RequestBuilder对象,然后调用Into方法,构建一个Request对象,并requestManager.track(target,request)跟踪这个请求,同时通过requestTracker.runRequest(request)来启动这个请求,调用SigleRequest --->begin()方法,然后通过Eegine --->load () 缓存检测机制,先检测活动缓存有没有,在检测LruResourceCache有没有,如果命中上面的二级内存缓存,直接调用onResourceReady()返回即可,如果上面的二级缓存都没有加载EngineJob中,使用GlideExecutor 构建一个新的异步任务,在执行Request请求之前,先检测DiskCache中有没有磁盘缓存

glide从网络上加载图片:Glide在调用load方法加载图片的时候,检测如果资源存在,直接调用onResourceReady()方法直接加载图片,如果资源不存在,首先从网络下载图片,并开启二个线程池,用于缓存图片。
内存缓存和磁盘缓存,网络缓存
DiskCacheStrategy.NONE 啥也不缓存
DiskCacheStrategy.SOURCE 只缓存全尺寸图
DiskCacheStrategy.RESULT 只缓存最终降低分辨后用到的图片

和Picasso的对比:
1.Glide可以加载Gif,picasso不能,2.glide默认的解码格式是RGB_565(4bit) ,Picasso默认的解码格式是ARGB888(8bit)更清晰 3.pacasso的with方法只接受context作为参数,但是glide可以接受context,fragment,activity,这样,glide加载图片的时候,能够和组件的生命周期保持一致。

3.Rxjava(https://gank.io/post/560e15be2dca930e00da1083#toc_4

(1).Rxjava一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序库。
(2).Rxjava原理就是类似于观察者模式
观察者模式面向的需求是:A 对象(观察者)对 B 对象(被观察者)的某种变化高度敏感,需要在 B 变化的一瞬间做出反应。举个例子,新闻里喜闻乐见的警察抓小偷,警察需要在小偷伸手作案的时候实施抓捕。在这个例子里,警察是观察者,小偷是被观察者,警察需要时刻盯着小偷的一举一动,才能保证不会漏过任何瞬间。程序的观察者模式和这种真正的『观察』略有不同,观察者不需要时刻盯着被观察者(例如 A 不需要每过 2ms 就检查一次 B 的状态),而是采用注册(Register)或者称为订阅(Subscribe)的方式,告诉被观察者:我需要你的某某状态,你要在它变化的时候通知我。 Android 开发中一个比较典型的例子是点击监听器 OnClickListener 。对设置 OnClickListener 来说, View 是被观察者, OnClickListener 是观察者,二者通过 setOnClickListener() 方法达成订阅关系。订阅之后用户点击按钮的瞬间,Android Framework 就会将点击事件发送给已经注册的 OnClickListener 。采取这样被动的观察方式,既省去了反复检索状态的资源消耗,也能够得到最高的反馈速度。当然,这也得益于我们可以随意定制自己程序中的观察者和被观察者,而警察叔叔明显无法要求小偷『你在作案的时候务必通知我』

RxJava 有四个基本概念:Observable (可观察者,即被观察者)、 Observer (观察者)、 subscribe (订阅)、事件。Observable 和 Observer 通过 subscribe() 方法实现订阅关系,从而 Observable 可以在需要的时候发出事件来通知 Observer。
 Observable.create(new Observable.OnSubscribe<String>() {
                    @Override
                    public void call(Subscriber<? super String> subscriber) {
                        //onNext可以调用多次
                        try {
                            subscriber.onNext("Hellow Rxjava");
                            subscriber.onNext("Hellow Rxjava");
                            //时间序列结束标记
                            subscriber.onCompleted();
                        }catch (Exception e){
                            subscriber.onError(e);
                        }
                    }
                }).subscribe(new Observer<String>() {//被观察者必须指定观察者或者订阅者,整个事件才可以
                    @Override
                    public void onCompleted() {
                        Log.i(TAG,"onCompleted:");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.i(TAG,"onError:"+e);
                    }

                    @Override
                    public void onNext(String s) {
                        Log.i(TAG,"onNext:"+s);
                    }
                });
在 RxJava 的 subscribe 过程中,Observer 也总是会先被转换成一个 Subscriber 再使用。所以如果你只想使用基本功能,选择 Observer 和 Subscriber 是完全一样的。它们的区别对于使用者来说主要有两点。

A:onStart():这是 Subscriber 增加的方法。
B: unsubscribe(): 这是 Subscriber 所实现的另一个接口 Subscription 的方法,用于取消订阅,
一般在这个方法调用前,可以使用 isUnsubscribed() 先判断一下状态。 unsubscribe() 这个方法很重要,因为在 subscribe() 之后, Observable 会持有 Subscriber 的引用,这个引用如果不能及时被释放,将有内存泄露的风险。所以最好保持一个原则:要在不再使用的时候尽快在合适的地方(例如 onPause() onStop() 等方法中)调用 unsubscribe() 来解除引用关系,以避免内存泄露的发生。
(3).操作符
(3-1).create,just,from操作符创建Observable被观察者对象

 Observable.just(1,2,3,4,5).subscribe(new Subscriber<Integer>() {
                    @Override
                    public void onCompleted() {
                        Log.i(TAG,"onCompleted:");
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.i(TAG,"onNext:"+integer);
                    }
                });
 Observable.from(new String[]{"AAA","BBB","CCC"}).subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.i(TAG, "onNext:" + s);

                    }
   }); 

(3-2)map,floatmap,filter ,take ,takelast,distinct,skip变换操作符

map操作符----将原Observable发射出来的数据转换为另外一种类型的数据
 Observable.just(666).map(new Func1<Integer, String>() {
                    @Override
                    public String call(Integer integer) {//Integer---->String
                        return integer+"";
                    }
                }).map(new Func1<String, Long>() {
                    @Override
                    public Long call(String s) {
                        return Long.parseLong(s);
                    }
                }).subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) {
                        Log.i(TAG,"call:"+aLong);
                    }
                });
floatmap操作符---作用类似于map又比map强大,map是单纯的数据类型的转换,而flapMap可以将原数转换成新的Observables,再将这些Observables的数据顺序缓存到一个新的队列中,在统一发射出来
List<Student> students= DataUtils.getStudentList();
                Observable.from(students).flatMap(new Func1<Student, Observable<String>>() {
                    @Override
                    public Observable<String> call(Student student) {
                        return Observable.from(student.getCourses());
                    }
                }).subscribe(new Observer<String>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable throwable) {

                    }

                    @Override
                    public void onNext(String s) {
                        Log.i("TAG","couseName:"+s.toString());
                    }
                });
filter操作符----对发射的数据做一个限制,只有满足条件的数据才会被发射
//对发射的数据做一个限制,只有满足条件的数据才会被发射
                Observable.just("hello","Rxjava","Nice to meet you").filter(new Func1<String, Boolean>() {
                    @Override
                    public Boolean call(String s) {
                        return s.length()>5;
                    }
                }).subscribe(new Observer<String>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable throwable) {

                    }

                    @Override
                    public void onNext(String s) {
                        Log.i("TAG","filter过滤后的数据:"+s.toString());
                    }
                });
distinct操作符----过滤掉重复项
 Observable.just("hello","hello","hello","Rxjava","Rxjava","Nice to meet you").filter(new Func1<String, Boolean>() {
                    @Override
                    public Boolean call(String s) {
                        return s.length()>5;
                    }
                }).subscribe(new Observer<String>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable throwable) {

                    }

                    @Override
                    public void onNext(String s) {
                        Log.i("TAG","distinct去除重复之后的数据:"+s.toString());
                    }
                });
Skip操作符----发射数据时忽略前N项数据(skpiLast忽略后N项数据)
  Observable.just("hello","Rxjava","Nice to meet you").skip(2).subscribe(new Observer<String>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable throwable) {

                    }

                    @Override
                    public void onNext(String s) {
                        Log.i("TAG","Skip之后的数据:"+s.toString());
                    }
                });
take操作符----只发射前N项的数据(takeLast与take想反,只取最后N项数据)
 Observable.just("hello","Rxjava","Nice to meet you").take(2).subscribe(new Observer<String>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable throwable) {

                    }

                    @Override
                    public void onNext(String s) {
                        Log.i("TAG","Take之后的数据:"+s.toString());
                    }
                });

另外还有一些其他的操作符 range,Interval,empty,error等(https://www.jianshu.com/p/eceb6b31d8cb

(3-3).线程调度Scheduler

Observable.just(1, 2, 3, 4)
    .subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
    .observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
    .subscribe(new Action1<Integer>() {
        @Override
        public void call(Integer number) {
            Log.d(tag, "number:" + number);
        }
    });

上面这段代码中,由于 subscribeOn(Schedulers.io()) 的指定,被创建的事件的内容 1、2、3、4 将会在 IO 线程发出;而由于 observeOn(AndroidScheculers.mainThread()) 的指定,因此 subscriber 数字的打印将发生在主线程 。事实上,这种在 subscribe() 之前写上两句 subscribeOn(Scheduler.io()) 和 observeOn(AndroidSchedulers.mainThread()) 的使用方式非常常见,它适用于多数的 『后台线程取数据,主线程显示』的程序策略

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • 一、RxJava操作符概述 RxJava中的操作符就是为了提供函数式的特性,函数式最大的好处就是使得数据处理简洁易...
    无求_95dd阅读 2,978评论 0 21
  • 注:只包含标准包中的操作符,用于个人学习及备忘参考博客:http://blog.csdn.net/maplejaw...
    小白要超神阅读 2,184评论 2 8
  • 参考:给 Android 开发者的 RxJava 详解-扔物线深入浅出RxJava 基础 "a library f...
    Vincen1024阅读 540评论 0 1
  • 一、RxJava操作符概述 RxJava中的操作符就是为了提供函数式的特性,函数式最大的好处就是使得数据处理简洁易...
    BrotherChen阅读 1,590评论 0 10
  • 一、RxJava操作符概述 RxJava中的操作符就是为了提供函数式的特性,函数式最大的好处就是使得数据处理简洁易...
    测天测地测空气阅读 626评论 0 1