43. RX思维的魅力

43. RX思维的魅力

43.1 在下载图片的前提下增加需求

在这里插入图片描述

加水印需求

在这里插入图片描述

在这里插入图片描述

现在的完整代码:

package com.dingjiaxiong.myrxjava;

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 java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

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

public class MainActivity extends AppCompatActivity {

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

    // 网络图片的链接地址
    private final static String PATH = "http://pcsource.upupoo.com/theme/2000858833/previewFix.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) {

         //如果采用传统开发方式,后面的开发者接手前面开发者的代码,就很痛苦(弊端)
        /**
         * TODO RX思维
         *
         * 起点 和 终点
         *
         * RxJava RXJS RxXXX  RX系列框架 为什么把所有函数都成为操作符 因为我们的函数要去操作  从起点 流向 终点7
         *
         */


        // 起点
        Observable.just(PATH)


                // 需求: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;
                    }
                })


                //需求 2 加水印
                .map(new Function<Bitmap, Bitmap>() {
                    @Override
                    public Bitmap apply(Bitmap bitmap) throws Throwable {
                        Paint paint = new Paint();
                        paint.setColor(Color.RED);
                        paint.setTextSize(88);
                        Bitmap bitmap_withShuiyin = drawTextToBitmap(bitmap, "DingJiaxiong学Android!", paint, 88, 88);

                        return bitmap_withShuiyin;
                    }
                })

 

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


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

                // 关联:观察者设计模式   关联 起点 和 终点  ==  订阅
                .subscribe(

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

                            // 订阅成功
                            @Override
                            public void onSubscribe(Disposable d) {
                                progressDialog = new ProgressDialog(MainActivity.this);
                                progressDialog.setTitle("RXjava Dingjiaxiong running...");
                                progressDialog.show();
                            }

                            // 上一层给我的响应
                            @Override
                            public void onNext(Bitmap bitmap) {
                                image.setImageBitmap(bitmap); // 显示到控件上
                            }

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

                            }

                            // 整个链条全部结束
                            @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;
    }

}

运行

在这里插入图片描述

奈斯

再加个需求,记录日志

在这里插入图片描述

在这里插入图片描述

// 需求 3 日志记录
                .map(new Function<Bitmap, Bitmap>() {
                    @NonNull
                    @Override
                    public Bitmap apply(@NonNull Bitmap bitmap) throws Throwable {
                        Date day=new Date();
                        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        System.out.println("下载时间" + df.format(day));
                        return bitmap;
                    }
                })

运行

在这里插入图片描述

妙啊

43.2 还有很多其他的操作符

这里贴上另一位博主的帖子:https://blog.csdn.net/chuyouyinghe/article/details/122806097

举个栗子

再加上一个按钮

在这里插入图片描述

public void action(View view) {
    String[] strings = {"AAA","BBB","CCC"};
    //起点
    Observable.fromArray(strings)

            //订阅:起点 和 终点
            .subscribe(new Consumer<String>() {
                @Override
                public void accept(String s) throws Throwable {
                    System.out.println(s);
                }
            });
}

在这里插入图片描述

43.3 自定义Observer解决问题
如果登陆成功,只想拿到 成功Bean == SuccessBean

如果登录失败,只想拿到 message string 类型

总Bean和成功Bean

ResponseResult.java

package com.dingjiaxiong.myrxjava.login.bean;

// 请求服务器 的 结果Bean  总Bean
public class ResponseResult {

    // 登录成功
    private SuccessBean data; // 成功Bean
    private int code;
    private String message;

    public ResponseResult(SuccessBean data, int code, String message) {
        this.data = data;
        this.code = code;
        this.message = message;
    }

    public ResponseResult() {
    }

    public SuccessBean getData() {
        return data;
    }

    public void setData(SuccessBean data) {
        this.data = data;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public String toString() {
        return "ResponseResult{" +
                "data=" + data +
                ", code=" + code +
                ", message='" + message + '\'' +
                '}';
    }
}

SuccessBean.java

package com.dingjiaxiong.myrxjava.login.bean;

// 登录 注册 成功的 Bean 信息
public class SuccessBean {

    private int id;
    private String name;

    public SuccessBean() {
    }

    public SuccessBean(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "SuccessBean{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}


定义登录引擎

LoginEngine.java

package com.dingjiaxiong.myrxjava.login.core;

import com.dingjiaxiong.myrxjava.login.bean.ResponseResult;
import com.dingjiaxiong.myrxjava.login.bean.SuccessBean;

import io.reactivex.rxjava3.core.Observable;
import okhttp3.Response;

public class LoginEngine {

    // 返回 起点
    public static Observable<ResponseResult> login(String name, String pwd) {

        // 最终返回 总Bean
        ResponseResult responseResult = new ResponseResult();

        if ("dingjiaxiong".equals(name) && "123".equals(pwd)) { // 登录成功

            // 创建 成功 Bean
            SuccessBean successBean = new SuccessBean();
            successBean.setId(45674565);
            successBean.setName("Dingjiaxiong 登录成功");

            /**
             * {
             *   data:{ xxxxxxx 登录成功的Bean xxxxxxx  SuccesBean   成功Bean }
             *   code:200
             *   message:"登录成功"
             * }
             */
            responseResult.setData(successBean);
            responseResult.setCode(200);
            responseResult.setMessage("登录成功");

        } else { // 登录失败

            /**
             * {
             *   data:null
             *   code:404
             *   message:"登录错误"
             * }
             */
            responseResult.setData(null);
            responseResult.setCode(404);
            responseResult.setMessage("登录错误");
        }

        // 起点
        return Observable.just(responseResult);
    }

}

new 一个新的Activity

在这里插入图片描述

创建自己的observer

package com.dingjiaxiong.myrxjava.login.core;


import com.dingjiaxiong.myrxjava.login.bean.ResponseResult;
import com.dingjiaxiong.myrxjava.login.bean.SuccessBean;

import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;


public abstract class CustomObserver implements Observer<ResponseResult> {

    public abstract void success(SuccessBean successBean);
    public abstract void error(String message);

    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onNext(ResponseResult responseResult) {
        if (responseResult.getData() == null) {
            error(responseResult.getMessage() + "请求失败");
        } else {
            success(responseResult.getData());
        }
    }

    @Override
    public void onError(Throwable e) {
        error(e.getMessage() + "错误详情");
    }

    @Override
    public void onComplete() {

    }
}


调用登录操作

LoginEngine.login("dingjiaxiong", "123")
                //返回起点
                .subscribe(new CustomObserver() {
                    @Override
                    public void success(SuccessBean successBean) {
                        System.out.println("dingjiaxiong" + "登录成功" + successBean.toString());
                    }

                    @Override
                    public void error(String message) {
                        System.out.println("登录失败" + message);
                    }
                });

在这里插入图片描述

更改清单文件,默认启动LoginActivity

在这里插入图片描述

运行

在这里插入图片描述

在这里插入图片描述

posted @ 2022-09-19 09:03  随遇而安==  阅读(28)  评论(0编辑  收藏  举报