安卓开发之RxJava的简单使用

前言

官方的定义:一个在Java VM上使用可观测的序列,组成异步的、基于事件的程序的库
RxJava 是一个响应式编程框架,采用观察者设计模式。所以自然少不了 Observable 和 Subscriber 这两个。
RxJava 是一个开源项目,地址:https://github.com/ReactiveX/RxJava
RxAndroid,用于 Android 开发,添加了 Android 用的接口。地址: https://github.com/ReactiveX/RxAndroid

RxJava的简单使用

1、环境准备

导入依赖

// 依赖RxAndroid 2X 的依赖库
    // 增加RxJava 2X 的依赖库
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
    implementation 'io.reactivex.rxjava2:rxjava:2.0.7'

网络权限

 <!-- 开启网络权限 -->
    <uses-permission android:name="android.permission.INTERNET" /> 

有时候还可能要加这个在项目清单的application中

 android:usesCleartextTraffic="true"

2、activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".simple01.MainActivity"
    android:orientation="vertical">

    <!-- RxJava来显示我们的图片 -->
    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="图片显示加载功能"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:onClick="showImageAction"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="常用操作符"
        android:onClick="action"
        />

</LinearLayout>

3、MianActivity.java

在这里插入图片描述

第一个按钮的点击事件包含三个需求

  1. 请求网络图片
  2. 给图片加水印
  3. 输出打印日志

第二个按钮绑定的点击事件就是对字符串数组遍历输出打印

package com.derry.rxjavastudy.simple01;

import androidx.appcompat.app.AppCompatActivity;

import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import com.derry.rxjavastudy.R;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

public class MainActivity extends AppCompatActivity {

    // 打印logcat日志的标签
    private final String TAG = MainActivity.class.getSimpleName();

    // 网络图片的链接地址
    private final static String PATH = "http://pic1.win4000.com/wallpaper/c/53cdd1f7c1f21.jpg";

    // 弹出加载框(正在加载中...)
    private ProgressDialog progressDialog;

    // ImageView控件,用来显示结果图像
    private ImageView image;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        image = findViewById(R.id.image);
    }

    /**
     * 图片显示加载功能
     *
     * @param view
     */
    public void showImageAction(View view) {

        /**
         * 如果我们采用传统方式 完成此功能,每位开发者的思想都不一样 (思维不同 )
         * A同学 线程池
         * B同学 new Thread + Handler
         * C同学 xxx
         * D同学 古老的方式
         * ....
         *
         * 如果采用传统开发方式,我们后面的开发者接手前面开发者的代码,就很痛苦(弊端)
         */


        /**
         * TODO RX思维
         *
         * 起点 和 终点
         *
         * RxJava RXJS RxXXX  RX系列框架 为什么把所有函数都成为操作符 因为我们的函数要去操作  从起点 流向 终点7
         *
         */

        // TODO 第二步
        // 起点
        Observable.just(PATH)

                // TODO 第三步
                // 需求:001 图片下载需求  PATH ---》 Bitmap
                .map(new Function<String, Bitmap>() {
                    @NonNull
                    @Override
                    public Bitmap apply(@NonNull String path) throws Exception {
                        try {
//                            Thread.sleep(2000); // 睡眠2秒钟

                            URL url = new URL(path);
                            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                            httpURLConnection.setConnectTimeout(5000); // 设置请求连接时长 5秒
                            int responseCode = httpURLConnection.getResponseCode(); // 才开始 request    拿到服务器的响应  200成功  404有问题 ...
                            if (responseCode == HttpURLConnection.HTTP_OK) {
                                InputStream inputStream = httpURLConnection.getInputStream();
                                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                                return bitmap;
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        return null;
                    }
                })

                // 需求:002 加水印
                .map(new Function<Bitmap, Bitmap>() {
                    @NonNull
                    @Override
                    public Bitmap apply(@NonNull Bitmap bitmap) throws Exception {
                        Paint paint = new Paint();
                        paint.setColor(Color.RED);
                        paint.setTextSize(88);
                        Bitmap shuiyingBitmap = drawTextToBitmap(bitmap, "韭菜盖饭", paint, 88, 88);
                        return shuiyingBitmap;
                    }
                })

                // 需求:003 日志记录需求
                .map(new Function<Bitmap, Bitmap>() {
                    @NonNull
                    @Override
                    public Bitmap apply(@NonNull Bitmap bitmap) throws Exception {
                        Log.e(TAG, "什么时候下载了图片 apply: " + System.currentTimeMillis() );
                        return bitmap;
                    }
                })


                // 给上面的分配异步线程(图片下载操作)
                .subscribeOn(Schedulers.io())


                // 终点分配 Android主线程
                .observeOn(AndroidSchedulers.mainThread())

                // TODO 导火索 点燃了  开始执行
                // 关联:观察者设计模式   关联 起点 和 终点  ==  订阅
                .subscribe(

                        // 终点
                        new Observer<Bitmap>() {

                            // TODO 第一步
                            // 订阅成功
                            @Override
                            public void onSubscribe(Disposable d) {
                                // 显示加载框
                                progressDialog = new ProgressDialog(MainActivity.this);
                                progressDialog.setTitle("RXJava Derry run 正在加载中..");
                                progressDialog.show();
                            }

                            // TODO 第四步 显示图片   水印的Bitmap
                            // 上一层给我的响应
                            @Override
                            public void onNext(Bitmap bitmap) {
                                image.setImageBitmap(bitmap); // 显示到控件上
                            }

                            // 链条思维发生了异常
                            @Override
                            public void onError(Throwable e) {

                            }

                            // TODO 第五步 整个链条思维全部结束
                            // 整个链条全部结束
                            @Override
                            public void onComplete() {
                                // 隐藏加载框
                                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;
    }

    /**
     * 常用操作符
     * @param view
     */
    public void action(View view) {

        String[] strings = {"AAA", "BBB", "CCC"};

        // for
        /*for (String string : strings) {

        }*/

        // 起点
        Observable.fromArray(strings)

                // 订阅:起点 和 终点
                .subscribe(new Consumer<String>() {

                    // 终点
                    @Override
                    public void accept(@NonNull String s) throws Exception {
                        Log.d(TAG, "accept: " + s);
                    }
                });

    }
}

4、效果预览

在这里插入图片描述
在这里插入图片描述

RxJava操作符

参考文章
https://www.jianshu.com/p/3fdd9ddb534b
https://blog.csdn.net/zengke1993/article/details/80388510

1、创建操作符

创建被观察者(Observable)对象&发送事件
在这里插入图片描述

2、转换操作符

变换被观察者(Observable)发送的事件。将Observable发送的数据按照一定的规则做一些变换,然后再将变换的数据发射出去。变换的操作符有map,flatMap,concatMap,switchMap,buffer,groupBy等等。
在这里插入图片描述

3、 合并操作符

组合多个被观察者(Observable)&合并需要发送的事件。包含:concatMap(),concat(), merge(),mergeArray(),concateArray(),reduce(),collect(),startWith(),zip(),count()等
在这里插入图片描述

4、功能操作符

辅助被观察者(Observable) 发送事件时实现一些功能性需求,如错误处理,线程调度。
在这里插入图片描述

5、过滤操作符

用于将Observable发送的数据进行过滤和选择。让Observable返回我们所需要的数据。过滤操作符有buffer(),filter(),skip(),take(),skipLast(),takeLast(),throttleFirst(),distainctUntilChange()。
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韭菜盖饭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值