Android+Rxjava3入门小例子--读取图片并显示

news/2024/7/3 16:54:42

第三次学习Rxjava了,这次一定要学会,至少入门吧。。。

为什么要学习这个东东呢?

经常碰到与安卓系统交互的外部设备是应答式的,就是你一步步的问它,它一步步的回答,例如某厂商的指纹仪进行指纹比对操作,需要的步骤如下:

打开设备-下载指纹特征码到缓冲区A-采集指纹到缓冲区B(循环等待)-再次采集-合成特征码-与缓冲区A对比

类似这样的需要一步步推进的业务流程,通常的做法是异步回调、或者消息订阅,能用是能用,但是怎么说呢?它有点混乱:回调-回调-回调~~,或者:消息-消息-消息~~,半个月后发现之前写的代码阅读起来有点困难,跳来跳去的。

既然有这样的好东西了就学一下吧,可是看next(1);next(2);next(3);这样的例子,完全不得门而入。

本文将完成两个小例子,第一个是从网络上下载一个图片,然后展示出来;第二个增加了一个步骤,在下载完毕后添加水印,然后再展示出来。

先看第一个例子。

1,由于用到了网络,需要在项目的AndroidManifest.xml文件中添加权限

<uses-permission android:name="android.permission.INTERNET" />

2,布局,仅有一个图像控件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".MainActivity">

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="centerCrop"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

3,主界面Activity


import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

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.Function;
import io.reactivex.rxjava3.schedulers.Schedulers;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getSimpleName();

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

    private static final String PATH = "https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png";

    private void testNetIo() {
        Observable.just(PATH).map(new Function<String, Bitmap>() {
                    @Override
                    public Bitmap apply(String s) throws Throwable {
                        URL url = new URL(s);
                        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                        int respCode = conn.getResponseCode();
                        if (respCode == HttpURLConnection.HTTP_OK) {
                            InputStream inputStream = conn.getInputStream();
                            return BitmapFactory.decodeStream(inputStream);
                        }
                        Log.d(TAG, "反馈其它:" + respCode);
                        return null;
                    }
                }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Bitmap>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        showProgressDialog();
                    }

                    @Override
                    public void onNext(@NonNull Bitmap bitmap) {
                        if(bitmap == null){
                            Log.e(TAG, "onNext反馈null");
                            return;
                        }

                        ((ImageView) MainActivity.this.findViewById(R.id.imageView1)).setImageBitmap(bitmap);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.d(TAG, "------onError----------" + e);
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "-----onComplete-----------");
                        dismissProgressDialog();
                    }
                });
    }

    private ProgressDialog progressDialog;

    public void showProgressDialog() {
        if (progressDialog == null) {
            progressDialog = new ProgressDialog(this);
            progressDialog.setIndeterminate(true);
            progressDialog.setCancelable(false);
        }
        progressDialog.setMessage("your message");
        progressDialog.show();
    }

    public void dismissProgressDialog() {
        if (progressDialog != null) {
            progressDialog.dismiss();
        }
    }
}

代码里使用了已经被抛弃的对话框方法,也没有优化代码,不要去管他,就是简单方便的表达用法就好了。

这样一个简单的例子就完成了,我也不懂为什么要just、为什么要map,就先这样写吧,到目前为止,它能够表达出来的流程性的特点并不明显,接下来增加一个添加水印的步骤,加强一下“流程”、“步骤”。

只需要在map方法的后面,再加一个map方法即可,像这样:

        Observable.just(PATH).map(new Function<String, Bitmap>() {
                    @Override
                    public Bitmap apply(String s) throws Throwable {
                        URL url = new URL(s);
                        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                        int respCode = conn.getResponseCode();
                        if (respCode == HttpURLConnection.HTTP_OK) {
                            InputStream inputStream = conn.getInputStream();
                            return BitmapFactory.decodeStream(inputStream);
                        }
                        Log.d(TAG, "反馈其它:" + respCode);
                        return null;
                    }
                })
                .map(new Function<Bitmap, Bitmap>() {//新添加的map方法
                    @Override
                    public Bitmap apply(Bitmap bitmap) throws Throwable {
                        return waterMarkCover(bitmap, "rxjava入门");
                    }
                })

看吧,要加一个步骤只要写一段map即可。

新添加的水印方法也是网上抄抄的,如下:

    private Bitmap waterMarkCover(Bitmap bitmap, String text) {
        if (bitmap == null) return null;
        Bitmap newImage = bitmap.copy(bitmap.getConfig(), true);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        Canvas canvas = new Canvas(newImage);
        paint.setColor(Color.RED);
        paint.setTextSize(100);
        Rect bounds = new Rect();
        paint.getTextBounds(text, 0, text.length(), bounds);
        canvas.drawText(text, 0, bounds.height(), paint);//bounds.height()是文字高度,你把它换成0试试就知道为什么要用文字高度了
        bitmap.recycle();
        return newImage;
    }


http://lihuaxi.xjx100.cn/news/1247063.html

相关文章

【CompareAndSwap底层原理】

文章目录 CompareAndSwap底层原理小故事 CompareAndSwap底层原理 CompareAndSwap&#xff08;CAS&#xff09;是一种并发编程中的操作&#xff0c;它可以判断一个变量的当前值是否与预期值相同&#xff0c;如果相同&#xff0c;就将该变量的值设置为新值。CAS操作通常用于多线…

Mini LED电视大热,“智能化”渐行渐远?

在中国&#xff0c;电视机几乎是每个家庭必备的家用电器。相较于手机、平板、电脑、学习机等产品而言&#xff0c;由于电视机的屏幕足够大&#xff0c;所以其带给用户的视觉体验会相对更好一些&#xff0c;而影响用户视觉体验的除了屏幕大小以外&#xff0c;还有显示技术。 前…

微信小程序实现选择地区demo,记录最近访问的地区

最终效果图&#xff1a; index.wxml <view class"container"><view class"search_contaniner"><view class"search_box"><input type"text" placeholder"省/市级/区县级" value"{{search_con…

1.5 掌握Scala内建控制结构(一)

一、条件表达式 &#xff08;一&#xff09;语法格式 if (条件) 值1 else 值2 &#xff08;二&#xff09;执行情况 条件为真&#xff0c;结果是值1&#xff1b;条件为假&#xff0c;结果是值2。如果if和else的返回结果同为某种类型&#xff0c;那么条件表达式结果也是那种…

10 个杀手级的Python自动化脚本,解放你的双手

重复性任务总是耗时且无聊&#xff0c;想一想你想要一张一张地裁剪 100 张照片或 Fetch API、纠正拼写和语法等工作&#xff0c;所有这些任务都很耗时&#xff0c;为什么不自动化它们呢&#xff1f;在今天的文章中&#xff0c;我将与你分享 10 个 Python [自动化脚本]。 所以&a…

网络编程与自动化(python)

20.1 网络编程与自动化概述 传统网络运维困境大家在日常的网络运维中是否遇到过如下问题: 设备升级:现网有数千台网络设备,你需要周期性、批量性地对设备进行升级。配置审计:企业年度需要对设备进行配置审计。例如要求所有设备开启sTelnet功能,以太网交换机配置生成树安全…

【mmcls】mmdet中使用mmcls的网络及预训练模型

mmcls现在叫mmpretrain&#xff0c;以前叫mmclassification&#xff0c;这里为了统一称为mmcls。在基于MM框架的下游任务&#xff0c;例如检测(mmdetection)中可以使用mmcls中的backbone进行特征提取&#xff0c;但这就需要知道网络的参数以及输出特征的维度。本文简单介绍了在…

Spring Boot进阶(48):SpringBoot之集成WebSocket及使用说明 | 超级详细,建议收藏

1. 前言&#x1f525; 对于很多小伙伴来说&#xff0c;项目现在都普遍前后端分离&#xff0c;各干各的事儿&#xff0c;在前后端进行服务调用才会有大面积的碰头&#xff0c;后端接口数据格式发生变更要通知前端&#xff0c;相反&#xff0c;前端有变化要告诉后端&#xff0c;这…