为什么学习RxJava ?
改变思维来提升效率
Rx思维生活中的例子:
起点(分发事件(PATH):我饿了)----------下楼-------去餐厅--------点餐----------> 终点(吃饭 消费事件)
Rx思维程序中的例子:
起点(分发事件:点击登录)----------登录API-------请求服务器--------获取响应码----------> 终点(更新UI登录成功 消费事件)
RxJava核心思想
起点(被观察者)(Observable)
终点(观察者)(Observer)
下载图片例子
平常思维写代码:
public class DownloadActivity extends AppCompatActivity {
// 打印logcat日志的标签
private static final String TAG = DownloadActivity.class.getSimpleName();
// 网络图片的链接地址
private final static String PATH = "https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png";
// 弹出加载框
private ProgressDialog progressDialog;
// ImageView控件,用来显示结果图像
private ImageView image;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download);
image = findViewById(R.id.image);
}
// 零零散散 麻烦 思维
public void downloadImageAction(View view) {
progressDialog = new ProgressDialog(this);
progressDialog.setTitle("下载图片中...");
progressDialog.show();
new Thread(new Runnable() {
@Override
public void run() {
try {
URL url = new URL(PATH);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(5000);
int responseCode = httpURLConnection.getResponseCode(); // 才开始 request
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = httpURLConnection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
Message message = handler.obtainMessage();
message.obj = bitmap;
handler.sendMessage(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
private final Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
Bitmap bitmap = (Bitmap) msg.obj;
image.setImageBitmap(bitmap);
if (progressDialog != null) progressDialog.dismiss();
return false;
}
});
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="downloadImageAction"
android:text="传统方式下载图片功能" />
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
RxJava思想写代码:
U型结构,卡片式编程
先从最顶端从到最底端
再从最低端冲到最顶端
public class DownloadActivity extends AppCompatActivity {
// 打印logcat日志的标签
private static final String TAG = DownloadActivity.class.getSimpleName();
// 网络图片的链接地址
private final static String PATH = "https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png";
// 弹出加载框
private ProgressDialog progressDialog;
// ImageView控件,用来显示结果图像
private ImageView image;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download);
image = findViewById(R.id.image);
}
public void rxJavaDownloadImageAction(View view) {
// 起点
// TODO 这是RxJava 的第二步 分发
Observable.just(PATH) // 内部会分发 PATH Stirng
// TODO 这是RxJava 的第三步 卡片拦截
.map(new Function<String, Bitmap>() {
@Override
public Bitmap apply(@io.reactivex.annotations.NonNull String s) throws Exception {
URL url = new URL(PATH);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(5000);
int responseCode = httpURLConnection.getResponseCode(); // 才开始 request
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = httpURLConnection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
}
return null;
}
})
.subscribeOn(Schedulers.io())// 给上面的代码分配异步线程
.observeOn(AndroidSchedulers.mainThread())//给下面的代码分配主线程
// 终点
.subscribe(
new Observer<Bitmap>() {
//订阅开始
@Override
public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {
// TODO 这是RxJava 的第一步 预备分发
progressDialog = new ProgressDialog(DownloadActivity.this);
progressDialog.setTitle("下载图片中...");
progressDialog.show();
}
//拿到事件
@Override
public void onNext(@io.reactivex.annotations.NonNull Bitmap bitmap) {
// TODO 这是RxJava 的第四步 显示UI
image.setImageBitmap(bitmap);
}
//错误事件
@Override
public void onError(@io.reactivex.annotations.NonNull Throwable e) {
}
//完成事件
@Override
public void onComplete() {
// TODO 这是RxJava 的第五步 完成事件
if (progressDialog != null) progressDialog.dismiss();
}
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="rxJavaDownloadImageAction"
android:text="RxJava方式下载图片功能" />
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
再来一个加水印的卡片:
public class DownloadActivity extends AppCompatActivity {
// 打印logcat日志的标签
private static final String TAG = DownloadActivity.class.getSimpleName();
// 网络图片的链接地址
private final static String PATH = "https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png";
// 弹出加载框
private ProgressDialog progressDialog;
// ImageView控件,用来显示结果图像
private ImageView image;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download);
image = findViewById(R.id.image);
}
/**
* 封装我们的操作
* upstream 上游
* downstream 下游
*/
public final static <UD> ObservableTransformer<UD, UD> rxud() {
return new ObservableTransformer<UD, UD>() {
@Override
public ObservableSource<UD> apply(Observable<UD> upstream) {
return upstream.subscribeOn(Schedulers.io()) // 给上面代码分配异步线程
.observeOn(AndroidSchedulers.mainThread()) // 给下面代码分配主线程;
.map(new Function<UD, UD>() {
@Override
public UD apply(UD ud) throws Exception {
Log.d(TAG, "apply: 在执行");
return ud;
}
});
// ..... ;
}
};
}
public void rxJavaDownloadImageAction(View view) {
// 起点
// TODO 这是RxJava 的第二步 分发
Observable.just(PATH) // 内部会分发 PATH Stirng
// TODO 这是RxJava 的第三步 卡片拦截
.map(new Function<String, Bitmap>() {
@Override
public Bitmap apply(@NonNull String s) throws Exception {
URL url = new URL(PATH);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(5000);
int responseCode = httpURLConnection.getResponseCode(); // 才开始 request
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = httpURLConnection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
}
return null;
}
})
.map(new Function<Bitmap, Bitmap>() {
@Override
public Bitmap apply(@NonNull Bitmap bitmap) throws Exception {
Paint paint = new Paint();
paint.setTextSize(90);
paint.setColor(Color.RED);
return drawTextToBitmap(bitmap, "puppy love",paint, 90 , 90);
}
})
.compose(rxud())
// 终点
.subscribe(
new Observer<Bitmap>() {
//订阅开始
@Override
public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {
// TODO 这是RxJava 的第一步 预备分发
progressDialog = new ProgressDialog(DownloadActivity.this);
progressDialog.setTitle("下载图片中...");
progressDialog.show();
}
//拿到事件
@Override
public void onNext(@io.reactivex.annotations.NonNull Bitmap bitmap) {
// TODO 这是RxJava 的第四步 显示UI
image.setImageBitmap(bitmap);
}
//错误事件
@Override
public void onError(@io.reactivex.annotations.NonNull Throwable e) {
}
//完成事件
@Override
public void onComplete() {
// TODO 这是RxJava 的第五步 完成事件
if (progressDialog != null) progressDialog.dismiss();
}
});
}
// 图片上绘制文字 加水印
private final Bitmap drawTextToBitmap(Bitmap bitmap, String text, Paint paint, int paddingLeft, int paddingTop) {
Bitmap.Config bitmapConfig = bitmap.getConfig();
paint.setDither(true); // 获取跟清晰的图像采样
paint.setFilterBitmap(true);// 过滤一些
if (bitmapConfig == null) {
bitmapConfig = Bitmap.Config.ARGB_8888;
}
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
canvas.drawText(text, paddingLeft, paddingTop, paint);
return bitmap;
}
}
如果哪一天不需要水印需求了就直接去掉.map 卡片就行了
逻辑图:
只能从左往右