参考学习:https://www.bilibili.com/video/BV1AD4y1D7X1?from=search&seid=12155248327851699054
添加依赖:
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
在build.gradle的Android中
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
然后加网络权限等权限
为什么要用Rxjava
然后我们要实现一个请求网络图片,如果我们不用Rxjava,那么每个人都是不同的想法,可能会new Thread ,可能会线程池,也可能会AsycTask等,而我们用Rxjava时就会有一个流式的过程,这样就会规范化操作,从起点到终点,通过被观察者Observable去订阅观察者Observer,分为上游和下游,在上游中去做耗时操作,在下游中去进行UI界面的更新,下面我们看一下代码
代码说明:
1.这里是一个按钮的点击事件,just中传入的是图片的url,然后通过map,先把一个String的url通过okhttp去转化为一个bitmap类型的,
2.然后第二个map是说当我们有一个新的需求的时候,只需要加一个map即可实现,这就是rxjava编程的好处,非常条理;
3.然后两行是去指定上游和下游的线程
4.然后去订阅,把被观察者和观察者去关联起来
5.其中log中的数字是执行的顺序
//使用RxJava就会把流程给规范化
//多个被观察者和一个观察者
case R.id.requestByRxjava:
//第二步
Observable.just(Constants.imageUrl)
//第三步
//第一个需求,把图片返回
//一个map就是一个被观察者
.map(new Function<String, Bitmap>() {
@Override
public Bitmap apply(String s) throws Throwable {
Log.e(TAG, "apply: 2" );
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(8, TimeUnit.SECONDS)
.build();
Request request = new Request.Builder()
.get()
.url(Constants.image1Url)
.build();
Response execute = okHttpClient.newCall(request).execute();
InputStream inputStream = execute.body().byteStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
}
})
//第二个需求:图片加水印
.map(new Function<Bitmap, Bitmap>() {
@Override
public Bitmap apply(Bitmap bitmap) throws Throwable {
Log.e(TAG, "apply: 3" );
bitmap = addTextWatermark(bitmap, "hello", 88, Color.RED, 88, 88, false, true);
return bitmap;
}
})
//上游分配耗时线程
.subscribeOn(Schedulers.io())
//下游分配主线程
.observeOn(AndroidSchedulers.mainThread())
//通过订阅 把被观察者和观察者关联起来
.subscribe(
new Observer<Bitmap>() {
@Override
//第一步
public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {
Log.e(TAG, "onSubscribe: 1" );
mProgressBarMore.setVisibility(View.VISIBLE);
}
//第四步
@Override
public void onNext(@io.reactivex.rxjava3.annotations.NonNull Bitmap bitmap) {
Log.e(TAG, "onNext: 4" );
mIvMore.setImageBitmap(bitmap);
}
//如果onError就不会执行onComplete,所以要在这里处理progress
@Override
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
mProgressBarMore.setVisibility(View.GONE);
}
//第五步,全部结束,和onNext的区别就是onNext可以执行多次,而onComplete只能执行一次
@Override
public void onComplete() {
Log.e(TAG, "onComplete: 5");
mProgressBarMore.setVisibility(View.GONE);
}
}
);
break;
顺便附上加水印的代码
public static Bitmap addTextWatermark(Bitmap bitmap, String content, int textSize, int color, float x, float y, boolean positionFlag, boolean recycle) {
if (isEmptyBitmap(bitmap) || content == null)
return null;
Bitmap ret = bitmap.copy(bitmap.getConfig(), true);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Canvas canvas = new Canvas(ret);
paint.setColor(color);
paint.setTextSize(textSize);
Rect bounds = new Rect();
paint.getTextBounds(content, 0, content.length(), bounds);
canvas.drawText(content, bitmap.getWidth() - x - bounds.width() - bounds.left, bitmap.getHeight() - bounds.height() - bounds.top - y, paint);
if (positionFlag) {
canvas.drawText(content, x, bitmap.getHeight() - bounds.height() - bounds.top - y, paint);
} else {
canvas.drawText(content, bitmap.getWidth() - x - bounds.width() - bounds.left, bitmap.getHeight() - bounds.height() - bounds.top - y, paint);
}
if (recycle && !bitmap.isRecycled())
bitmap.recycle();
return ret;
}
public static boolean isEmptyBitmap(Bitmap src) {
return src == null || src.getWidth() == 0 || src.getHeight() == 0;
}
顺便附上普通方法去实现请求网络图片
case R.id.requestByNormal:
//程序员去考虑一个事情每一个人都考虑得不同的方案
mProgressBarMore.setVisibility(View.VISIBLE);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(8, TimeUnit.SECONDS)
.build();
Request request = new Request.Builder()
.get()
.url(Constants.imageUrl)
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
InputStream inputStream = response.body().byteStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
Message message = mHandler.obtainMessage();
message.obj = bitmap;
mHandler.sendMessage(message);
}
});
break;
private final Handler mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
if (mProgressBarMore != null) {
mProgressBarMore.setVisibility(View.GONE);
}
Bitmap bitmap = (Bitmap) message.obj;
mIvMore.setImageBitmap(bitmap);
return false;
}
});