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三级缓存机制源码分析
(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()) 的使用方式非常常见,它适用于多数的 『后台线程取数据,主线程显示』的程序策略