栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

RxJava2的多个doOnNext使用(包含图片与Base64互转、RxJava2的基础使用)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

RxJava2的多个doOnNext使用(包含图片与Base64互转、RxJava2的基础使用)

完成需求 UI线程->异步线程->UI线程->异步线程->异步线程->UI线程 多次频繁切换

具体需求:

(1)获取项目assets文件夹内的图片。
(2)图片文件转bitmap。
(3)bitmap压缩。
(4)压缩过的bitmap转成图片文件。
(5)图片文件转Base64。
(6)Base64转图片文件图片。
(7)图片文件转bitmap。

以下代码在项目里,项目地址:https://gitee.com/urasaki/RxJava2AndRetrofit2

1.先申请权限,关于如何申请权限请查看RxPermissions的使用(简单实用)_ErwinNakajima的博客-CSDN博客_rxpermissions

2.添加RxJava2依赖(如果同步失败,可能是因为公司的网络有好多情况下连不到Google的仓库,所以就要连接自己的手机热点进行同步,手机热点一般会同步成功的,但是注意流量消耗)。

//rxjava2框架導入
    api 'io.reactivex.rxjava2:rxjava:2.2.10'
    api 'io.reactivex.rxjava2:rxandroid:2.1.1'

        使用RxPermissions搭配RxLifecycle3

//1.解决rxjava导致的内存泄漏的框架導入
    api 'com.trello.rxlifecycle3:rxlifecycle:3.1.0'
    // If you want to bind to Android-specific lifecycles
    api 'com.trello.rxlifecycle3:rxlifecycle-android:3.1.0'
    // If you want pre-written Activities and Fragments you can subclass as providers
    api 'com.trello.rxlifecycle3:rxlifecycle-components:3.1.0'
    // If you want pre-written support preference Fragments you can subclass as providers
    api 'com.trello.rxlifecycle3:rxlifecycle-components-preference:3.1.0'
    // If you want to use Android Lifecycle for providers
    api 'com.trello.rxlifecycle3:rxlifecycle-android-lifecycle:3.1.0'
    // If you want to use Kotlin syntax
    api 'com.trello.rxlifecycle3:rxlifecycle-kotlin:3.1.0'
    // If you want to use Kotlin syntax with Android Lifecycle
    api 'com.trello.rxlifecycle3:rxlifecycle-android-lifecycle-kotlin:3.1.0'
    // If you want to use Navi for providers
    // DEPRECATED: Use rxlifecycle-android-lifecycle instead. This will be removed in a future release.
    api 'com.trello.rxlifecycle3:rxlifecycle-navi:3.1.0'

3.在AndroidManifest.xml中添加自己需要用到的权限。


    
    
    
    

    

4.Bean类。

package com.phone.base64_and_file.bean;

import android.graphics.Bitmap;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class Base64AndFileBean {

    private String dirsPath;
    private String dirsPathCompressed;
    private String dirsPathCompressedRecover;
    private File file;
    private File fileCompressed;
    private File fileCompressedRecover;
    private Bitmap bitmap;
    private Bitmap bitmapCompressed;
    private Bitmap bitmapCompressedRecover;
    public String base64Str;
    private String txtFilePath;
    private List base64StrList = new ArrayList<>();

    public String getDirsPath() {
        return dirsPath;
    }

    public void setDirsPath(String dirsPath) {
        this.dirsPath = dirsPath;
    }

    public String getDirsPathCompressed() {
        return dirsPathCompressed;
    }

    public void setDirsPathCompressed(String dirsPathCompressed) {
        this.dirsPathCompressed = dirsPathCompressed;
    }

    public String getDirsPathCompressedRecover() {
        return dirsPathCompressedRecover;
    }

    public void setDirsPathCompressedRecover(String dirsPathCompressedRecover) {
        this.dirsPathCompressedRecover = dirsPathCompressedRecover;
    }

    public File getFile() {
        return file;
    }

    public void setFile(File file) {
        this.file = file;
    }

    public File getFileCompressed() {
        return fileCompressed;
    }

    public void setFileCompressed(File fileCompressed) {
        this.fileCompressed = fileCompressed;
    }

    public File getFileCompressedRecover() {
        return fileCompressedRecover;
    }

    public void setFileCompressedRecover(File fileCompressedRecover) {
        this.fileCompressedRecover = fileCompressedRecover;
    }

    public Bitmap getBitmap() {
        return bitmap;
    }

    public void setBitmap(Bitmap bitmap) {
        this.bitmap = bitmap;
    }

    public Bitmap getBitmapCompressed() {
        return bitmapCompressed;
    }

    public void setBitmapCompressed(Bitmap bitmapCompressed) {
        this.bitmapCompressed = bitmapCompressed;
    }

    public Bitmap getBitmapCompressedRecover() {
        return bitmapCompressedRecover;
    }

    public void setBitmapCompressedRecover(Bitmap bitmapCompressedRecover) {
        this.bitmapCompressedRecover = bitmapCompressedRecover;
    }

    public String getBase64Str() {
        return base64Str;
    }

    public void setBase64Str(String base64Str) {
        this.base64Str = base64Str;
    }

    public String getTxtFilePath() {
        return txtFilePath;
    }

    public void setTxtFilePath(String txtFilePath) {
        this.txtFilePath = txtFilePath;
    }

    public List getBase64StrList() {
        return base64StrList;
    }

    public void setBase64StrList(List base64StrList) {
        this.base64StrList.clear();
        this.base64StrList.addAll(base64StrList);
    }
}

5.BitmapManager代码。

package com.phone.base64_and_file;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ImageFormat;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.YuvImage;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import com.phone.common_library.manager.LogManager;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.nio.ByteBuffer;
import java.text.DecimalFormat;

import id.zelory.compressor.Compressor;

public class BitmapManager {

    private static final String TAG = "BitmapManager";
    
    public static final int ROTATE0 = 0;
    
    public static final int ROTATE90 = 90;
    
    public static final int ROTATE180 = 180;
    
    public static final int ROTATE270 = 270;
    
    public static final int ROTATE360 = 360;
    
    public static final int PIC_COMPRESS_SIZE = 4;
    
    public static final int IMAGEBOUND = 128;
    
    public static final int MAXLENTH = 1024;
    
    private static final boolean DEBUG = false;
    
    private static final int QUALITY = 100;
    
    private static final int DEFAULT_MAX_SIZE_CELL_NETWORK = 600;
    
    private static final int QUESTION_MAX_SIZE_CELL_NETWORK = 1024;
    
    private static final int QUESTION_IMAGE_JPG_QUALITY = 75;
    
    private static final int DEFAULT_IMAGE_JPG_QUALITY = 50;
    
    private static final int CONNECTTIMEOUT = 3000;

    
    private BitmapManager() {
    }

    
    public static Bitmap createBitmap(Bitmap bitmap, Bitmap mark) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        int mW = mark.getWidth();
        int mH = mark.getHeight();
        Bitmap newbitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);// 创建一个长宽一样的位图

        Canvas cv = new Canvas(newbitmap);
        cv.drawBitmap(bitmap, 0, 0, null);// 在 0,0坐标开始画入bitmap
        cv.drawBitmap(mark, w - mW, h - mH, null);// 在右下角画入水印mark
        cv.save();// 保存
        cv.restore();// 存储
        return newbitmap;
    }

    
    public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Matrix matrix = new Matrix();
        float scaleWidht = ((float) w / width);
        float scaleHeight = ((float) h / height);
        matrix.postScale(scaleWidht, scaleHeight);
        return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
    }

    
    public static Bitmap rotate(Bitmap bitmap, int angle) {
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                bitmap.getHeight(), matrix, true);
    }

    
    public static Bitmap createCircleBitmap(Bitmap source, int strokeWidth, boolean bl, int edge, int color) {

        int diameter = source.getWidth() < source.getHeight() ? source.getWidth() : source.getHeight();
        Bitmap target = Bitmap.createBitmap(diameter, diameter, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(target);//创建画布

        Paint paint = new Paint();
        paint.setAntiAlias(true);
        canvas.drawCircle(diameter / 2, diameter / 2, diameter / 2, paint);//绘制圆形
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//取相交裁剪
        canvas.drawBitmap(source, strokeWidth, strokeWidth, paint);
        if (bl) {
            if (color == 0) color = 0xFFFEA248;//默认橘黄色
            paint.setColor(color);
            paint.setStyle(Paint.Style.STROKE);//描边
            paint.setStrokeWidth(edge);
            canvas.drawCircle(diameter / 2, diameter / 2, diameter / 2, paint);
        }
        return target;
    }

    
    public static Bitmap createCornerBitmap(Bitmap bitmap, int rx, int ry, boolean bl, int edge, int color) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);//创建画布

        Paint paint = new Paint();
        paint.setAntiAlias(true);
        Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        RectF rectF = new RectF(rect);
        canvas.drawRoundRect(rectF, rx, ry, paint);//绘制圆角矩形
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//取相交裁剪
        canvas.drawBitmap(bitmap, rect, rect, paint);
        if (bl) {
            if (color == 0) color = 0xFFFEA248;//默认橘黄色
            paint.setColor(color);
            paint.setColor(color);
            paint.setStyle(Paint.Style.STROKE);//描边
            paint.setStrokeWidth(edge);
            canvas.drawRoundRect(rectF, rx, ry, paint);
        }
        return output;
    }

    
    public static Bitmap cropBitmap(Bitmap bitmap, float wScale, float hScale) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();

        int wh = (int) (w * wScale);
        int hw = (int) (h * hScale);

        int retX = (int) (w * (1 - wScale) / 2);
        int retY = (int) (h * (1 - hScale) / 2);

        return Bitmap.createBitmap(bitmap, retX, retY, wh, hw, null, false);
    }

    
    public static Bitmap createReflectionBitmap(Bitmap bitmap, float region) {

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Matrix matrix = new Matrix();
        matrix.preScale(1, -1);//镜像缩放
        Bitmap reflectionBitmap = Bitmap.createBitmap(
                bitmap, 0
                , (int) (height * (1 - region))//从哪个点开始绘制
                , width
                , (int) (height * region)//绘制多高
                , matrix, false);

        Bitmap reflectionWithBitmap = Bitmap.createBitmap(width, height + (int) (height * region),
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(reflectionWithBitmap);
        canvas.drawBitmap(bitmap, 0, 0, null);
        canvas.drawBitmap(reflectionBitmap, 0, height, null);

        LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0,
                reflectionWithBitmap.getHeight()
                , 0x70ffffff, 0x00ffffff, Shader.TileMode.CLAMP);

        Paint paint = new Paint();
        paint.setShader(shader);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));//取两层绘制交集。显示下层。
        canvas.drawRect(0, height, width, reflectionWithBitmap.getHeight(), paint);
        return reflectionWithBitmap;
    }

    
    public static Bitmap compressBitmap(Bitmap bitmap, float many) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, (int) many * 100, baos);
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        return BitmapFactory.decodeStream(isBm, null, null);
    }

    
    public static Bitmap imageZoom(Bitmap bitmap, double maxSize) {
        // 将bitmap放至数组中,意在获得bitmap的大小(与实际读取的原文件要大)
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // 格式、质量、输出流
        bitmap.compress(Bitmap.CompressFormat.PNG, 70, baos);
        byte[] b = baos.toByteArray();
        // 将字节换成KB
        double mid = b.length / 1024;
        // 获取bitmap大小 是允许最大大小的多少倍
        double i = mid / maxSize;
        // 判断bitmap占用空间是否大于允许最大空间 如果大于则压缩 小于则不压缩
        doRecycledIfNot(bitmap);
        if (i > 1) {
            // 缩放图片 此处用到平方根 将宽带和高度压缩掉对应的平方根倍
            // (保持宽高不变,缩放后也达到了最大占用空间的大小)
            return scaleWithWH(bitmap, bitmap.getWidth() / Math.sqrt(i),
                    bitmap.getHeight() / Math.sqrt(i));
        }
        return null;
    }

    
    public static Bitmap scaleWithWH(Bitmap bitmap, double w, double h) {
        if (w == 0 || h == 0 || bitmap == null) {
            return bitmap;
        } else {
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();

            Matrix matrix = new Matrix();
            float scaleWidth = (float) (w / width);
            float scaleHeight = (float) (h / height);

            matrix.postScale(scaleWidth, scaleHeight);
            return Bitmap.createBitmap(bitmap, 0, 0, width, height,
                    matrix, true);
        }
    }

    
    public static Bitmap getBitmap(byte[] data, int width, int height) {
        Bitmap bitmap;
        YuvImage yuvimage = new YuvImage(data, ImageFormat.NV21, width, height, null);
        //data是onPreviewFrame参数提供
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        yuvimage.compressToJpeg(new Rect(0, 0, yuvimage.getWidth(), yuvimage.getHeight()), 100, baos);//
        // 80--JPG图片的质量[0-100],100最高
        byte[] rawImage = baos.toByteArray();
        BitmapFactory.Options options = new BitmapFactory.Options();
        SoftReference softRef = new SoftReference(BitmapFactory.decodeByteArray(rawImage, 0, rawImage
                .length, options));
        bitmap = softRef.get();
        return bitmap;
    }

    
    public static Bitmap getBitmapResources(Context context, int resId) {
        return BitmapFactory.decodeResource(context.getResources(), resId);
    }

    
    public static Bitmap getBitmapPath(String path) {
        return BitmapFactory.decodeFile(path);
    }

    
    public static boolean saveFile(String path, Bitmap bmp) {
        if (TextUtils.isEmpty(path) || bmp == null) return false;

        File file = new File(path);
        if (file.exists()) {
            file.delete();
        } else {
            File p = file.getParentFile();
            if (!p.exists()) {
                p.mkdirs();
            }
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        try {
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bmp.compress(Bitmap.CompressFormat.JPEG, 100, bos);
            bos.flush();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }

    
    public static void doRecycledIfNot(Bitmap bitmap) {
        if (!bitmap.isRecycled()) {
            bitmap.recycle();
        }
    }

    
    public static Bitmap scaleImage(Bitmap resBitmap, int desWidth, int desHeight) {
        int resWidth = resBitmap.getWidth();
        int resHeight = resBitmap.getHeight();
        if (resHeight > desHeight || resWidth > desWidth) {
            // 计算出实际宽高和目标宽高的比率
            final float heightRatio = (float) desHeight / (float) resHeight;
            final float widthRatio = (float) desWidth / (float) resWidth;
            float scale = heightRatio < widthRatio ? heightRatio : widthRatio;
            LogManager.i(TAG, "scaleImage scale*****" + scale);
            //開平方會有一點損失精度
            float prescription = (float) Math.sqrt(scale);
//            float prescription2 = (float) Math.sqrt(prescription);
            LogManager.i(TAG, "scaleImage prescription*****" + prescription);
//            LogManager.i(TAG, "scaleImage prescription2*****" + prescription2);
            Bitmap bitmap = null;
            //循環壓縮bitmap,防止一次壓縮bitmap卡頓問題(子線程把主線成卡頓了)
            for (int i = 0; i < 2; i++) {
                if (bitmap != null) {
                    bitmap = scale(bitmap, prescription);
//                    bitmap = scale(bitmap, prescription2);
                } else {
                    bitmap = scale(resBitmap, prescription);
//                    bitmap = scale(resBitmap, prescription2);
                }
                LogManager.i(TAG, i + "scaleImage prescription*****" + prescription);
//                LogManager.i(TAG, i + "scaleImage prescription2*****" + prescription2);
            }
            return bitmap;
        }
        return resBitmap;
    }

    
    private static Bitmap scale(Bitmap bitmap, float scale) {
        Matrix matrix = new Matrix();
        matrix.postScale(scale, scale);
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    }

    
    public static Bitmap scale(Bitmap bitmap, int w, int h) {
        if (bitmap == null) {
            return null;
        }
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Matrix matrix = new Matrix();
        float scaleWidth = ((float) w / width);
        float scaleHeight = ((float) h / height);
        matrix.postScale(scaleWidth, scaleHeight);
        return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);

    }

    
    public static Uri saveTakePictureImage(Context context, byte[] data) {
        File file = context.getExternalFilesDir("file1");
        file = new File(file.getAbsolutePath() + File.separator + System.currentTimeMillis() + ".jpg");
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            fos.write(data);
            fos.flush();
        } catch (Exception e) {
            e.printStackTrace();

            // 异常时删除保存失败的文件
            try {
                if (file != null && file.exists() && file.isFile()) {
                    file.delete();
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }

            return null;
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        Log.e(TAG, file.getAbsolutePath());
        return Uri.fromFile(file);
    }

    
    public static Bitmap yuvToBitmap(byte[] data, int width, int height) {
        int frameSize = width * height;
        int[] rgba = new int[frameSize];

        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int y = (0xff & ((int) data[i * width + j]));
                int u = (0xff & ((int) data[frameSize + (i >> 1) * width + (j & ~1) + 0]));
                int v = (0xff & ((int) data[frameSize + (i >> 1) * width + (j & ~1) + 1]));
                y = y < 16 ? 16 : y;

                int r = Math.round(1.164f * (y - 16) + 1.596f * (v - 128));
                int g = Math.round(1.164f * (y - 16) - 0.813f * (v - 128) - 0.391f * (u - 128));
                int b = Math.round(1.164f * (y - 16) + 2.018f * (u - 128));

                r = r < 0 ? 0 : (r > 255 ? 255 : r);
                g = g < 0 ? 0 : (g > 255 ? 255 : g);
                b = b < 0 ? 0 : (b > 255 ? 255 : b);

                rgba[i * width + j] = 0xff000000 + (b << 16) + (g << 8) + r;
            }
        }

        Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        bmp.setPixels(rgba, 0, width, 0, 0, width, height);
        return bmp;
    }

    
    public static Bitmap depthToBitmap(byte[] depthBytes, int width, int height) {
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        int[] argbData = new int[width * height];
        for (int i = 0; i < width * height; i++) {
            argbData[i] = (((int) depthBytes[i * 2] + depthBytes[i * 2 + 1] * 256) / 10 & 0x000000ff)
                    | ((((int) depthBytes[i * 2] + depthBytes[i * 2 + 1] * 256) / 10) & 0x000000ff) << 8
                    | ((((int) depthBytes[i * 2] + depthBytes[i * 2 + 1] * 256) / 10) & 0x000000ff) << 16
                    | 0xff000000;

        }
        bitmap.setPixels(argbData, 0, width, 0, 0, width, height);
        return bitmap;
    }

    
    public static Bitmap rGBToBitmap(byte[] bytes, int width, int height) {
        // use Bitmap.Config.ARGB_8888 instead of type is OK
        Bitmap stitchBmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        byte[] rgba = new byte[width * height * 4];
        for (int i = 0; i < width * height; i++) {
            byte b1 = bytes[i * 3 + 0];
            byte b2 = bytes[i * 3 + 1];
            byte b3 = bytes[i * 3 + 2];
            // set value
            rgba[i * 4 + 0] = b1;
            rgba[i * 4 + 1] = b2;
            rgba[i * 4 + 2] = b3;
            rgba[i * 4 + 3] = (byte) 255;
        }
        stitchBmp.copyPixelsFromBuffer(ByteBuffer.wrap(rgba));
        return stitchBmp;
    }

    
    public static Bitmap bGRToBitmap(byte[] bytes, int width, int height) {
        // use Bitmap.Config.ARGB_8888 instead of type is OK
        Bitmap stitchBmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        byte[] rgba = new byte[width * height * 4];
        for (int i = 0; i < width * height; i++) {
            byte b1 = bytes[i * 3 + 0];
            byte b2 = bytes[i * 3 + 1];
            byte b3 = bytes[i * 3 + 2];
            // set value
            rgba[i * 4 + 0] = b3;
            rgba[i * 4 + 1] = b2;
            rgba[i * 4 + 2] = b1;
            rgba[i * 4 + 3] = (byte) 255;
        }
        stitchBmp.copyPixelsFromBuffer(ByteBuffer.wrap(rgba));
        return stitchBmp;
    }

    public static byte[] aRGBToR(byte[] bytes, int width, int height) {
        byte[] IR = new byte[width * height];
        for (int i = 0; i < width * height; i++) {
            IR[i] = bytes[i * 4];
        }
        return IR;
    }

//    
//    public static Bitmap getInstaceBmp(BDFaceImageInstance newInstance) {
//        Bitmap transBmp = null;
//        if (newInstance.imageType == BDFaceSDKCommon.BDFaceImageType.BDFACE_IMAGE_TYPE_RGBA) {
//            transBmp = Bitmap.createBitmap(newInstance.width, newInstance.height, Bitmap.Config.ARGB_8888);
//            transBmp.copyPixelsFromBuffer(ByteBuffer.wrap(newInstance.data));
//        } else if (newInstance.imageType == BDFaceSDKCommon.BDFaceImageType.BDFACE_IMAGE_TYPE_BGR) {
//            transBmp = BitmapManager.BGR2Bitmap(newInstance.data, newInstance.width, newInstance.height);
//        } else if (newInstance.imageType == BDFaceSDKCommon.BDFaceImageType.BDFACE_IMAGE_TYPE_YUV_NV21) {
//            transBmp = BitmapManager.yuv2Bitmap(newInstance.data, newInstance.width, newInstance.height);
//        } else if (newInstance.imageType == BDFaceSDKCommon.BDFaceImageType.BDFACE_IMAGE_TYPE_GRAY) {
//            transBmp = Depth2Bitmap(newInstance.data, newInstance.width, newInstance.height);
//        }
//        return transBmp;
//    }

    
    public static Bitmap getBitmap(String path) {
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        Bitmap bm = null;
        try {
            fis = new FileInputStream(path);
            BitmapFactory.Options options = new BitmapFactory.Options();
//            options.inSampleSize = 8;//图片的长宽都是原来的1/8
            bis = new BufferedInputStream(fis);
            bm = BitmapFactory.decodeStream(bis, null, options);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bm;
    }

    
    public static InputStream bitmapToInputStream(Bitmap bitmap) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        ByteArrayInputStream byteArrInputStream = new ByteArrayInputStream(
                baos.toByteArray());

        return byteArrInputStream;
    }

    
    public static byte[] readStream(String imagepath) {
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        ByteArrayOutputStream baos = null;
        try {
            fis = new FileInputStream(imagepath);
            bis = new BufferedInputStream(fis);

            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while (-1 != (len = bis.read(buffer))) {
                baos.write(buffer, 0, len);
            }
            //刷新此输出流并强制写出所有缓冲的输出字节
            baos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bis != null) {
                    bis.close();
                }
                if (baos != null) {
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return baos.toByteArray();
    }

    
    public static File saveFile(Bitmap bitmap, String dirsPath, String fileName) {
        File dirs = new File(dirsPath);
        if (!dirs.exists()) {
            dirs.mkdirs();
        }
        File captureFile = new File(dirs, fileName);
        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(new FileOutputStream(captureFile));
            //刷新此输出流并强制写出所有缓冲的输出字节
            bos.flush();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return captureFile;
    }

    

    public static long getFileSize(File file) {
        long size = 0;
        if (file.exists()) {
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                size = bis.available();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return size;
        }
        return 0;
    }

    
    public static String getDataSize(long size) {
        DecimalFormat formater = new DecimalFormat("####.00");
        if (size < 1024) {
            return size + "bytes";
        } else if (size < 1024 * 1024) {
            float kbsize = size / 1024f;
            return formater.format(kbsize) + "KB";
        } else if (size < 1024 * 1024 * 1024) {
            float mbsize = size / 1024f / 1024f;
            return formater.format(mbsize) + "MB";
        } else if (size < 1024 * 1024 * 1024 * 1024) {
            float gbsize = size / 1024f / 1024f / 1024f;
            return formater.format(gbsize) + "GB";
        } else {
            return "size: error";
        }
    }

    
    public static File initCompressorIO(Context context, String path, String dirsPath) {
        File dirs2 = new File(dirsPath);
        if (!dirs2.exists()) {
            dirs2.mkdirs();
        }

        File file = null;
        try {
            file = new Compressor(context)
//                    .setMaxWidth(1280)
//                    .setMaxHeight(960)
                    .setQuality(50)
                    .setCompressFormat(Bitmap.CompressFormat.PNG)
                    .setDestinationDirectoryPath(dirsPath)
                    .compressToFile(new File(path));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    public static File getAssetFile(Context context, String dirsPath, String assetFileName) {
        AssetManager assetManager = context.getAssets();
        File dirs = new File(dirsPath);
        if (!dirs.exists()) {
            dirs.mkdirs();
        }
        File file = new File(dirs, assetFileName);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        InputStream is = null;
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        try {
            is = assetManager.open(assetFileName);
            bis = new BufferedInputStream(is);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);

            byte[] buffer = new byte[1024];
            int len = 0;
            while (-1 != (len = bis.read(buffer))) {
                bos.write(buffer, 0, len);
            }
            //刷新此输出流并强制写出所有缓冲的输出字节
            bos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return file;
    }

    
    public static Bitmap base64ToBitmap(String base64String) {
        base64String = Uri.decode(base64String);
        byte[] decode = Base64.decode(base64String, Base64.DEFAULT);
        Bitmap bitmap = BitmapFactory.decodeByteArray(decode, 0, decode.length);
        return bitmap;
    }

}

5.doOnNext的使用的主要代码。

    
    private void initBase64AndFileTask() {
        Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter emitter) throws Exception {
                LogManager.i(TAG, "threadName*****" + Thread.currentThread().getName());
                showLoading();
                emitter.onNext(0);
            }
        }).subscribeOn(AndroidSchedulers.mainThread()) //给上面分配了UI线程
//                .observeOn(AndroidSchedulers.mainThread()) //给下面分配了UI线程
//                .doOnNext(new Consumer() {
//                    @Override
//                    public void accept(Integer integer) throws Exception {
//                        LogManager.i(TAG, "threadName*****" + Thread.currentThread().getName());
//                        showLoading();
//                    }
//                })
                .observeOn(Schedulers.io()) //给下面分配了异步线程
                .map(new Function() {
                    @Override
                    public Base64AndFileBean apply(Integer integer) throws Exception {
                        LogManager.i(TAG, "threadName2*****" + Thread.currentThread().getName());
                        File file = BitmapManager.getAssetFile(baseApplication, dirsPath, "picture_large.png");
                        base64AndFileBean.setFile(file);
                        return base64AndFileBean;
                    }
                })
                .observeOn(Schedulers.io()) //给下面分配了异步线程
                .doOnNext(new Consumer() {
                    @Override
                    public void accept(Base64AndFileBean base64AndFileBean) throws Exception {
                        LogManager.i(TAG, "threadName3*****" + Thread.currentThread().getName());
                        //把图片转化成bitmap
                        Bitmap bitmap = BitmapManager.getBitmap(base64AndFileBean.getFile().getAbsolutePath());
                        base64AndFileBean.setBitmap(bitmap);
                    }
                })
                .observeOn(Schedulers.io()) //给下面分配了异步线程
                .doOnNext(new Consumer() {
                    @Override
                    public void accept(Base64AndFileBean base64AndFileBean) throws Exception {
                        LogManager.i(TAG, "threadName4*****" + Thread.currentThread().getName());
                        //再压缩bitmap
                        Bitmap bitmapCompressed = BitmapManager.scaleImage(base64AndFileBean.getBitmap(), 1280, 960);
                        base64AndFileBean.setBitmapCompressed(bitmapCompressed);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread()) //给下面分配了异步线程
                .doOnNext(new Consumer() {
                    @Override
                    public void accept(Base64AndFileBean base64AndFileBean) throws Exception {
                        LogManager.i(TAG, "threadName5*****" + Thread.currentThread().getName());
                        //展示压缩过的图片
                        tevCompressedPicture.setVisibility(View.GONE);
                        imvCompressedPicture.setVisibility(View.VISIBLE);
                        imvCompressedPicture.setImageBitmap(base64AndFileBean.getBitmapCompressed());
                    }
                })
                .observeOn(Schedulers.io()) //给下面分配了异步线程
                .doOnNext(new Consumer() {
                    @Override
                    public void accept(Base64AndFileBean base64AndFileBean) throws Exception {
                        LogManager.i(TAG, "threadName6*****" + Thread.currentThread().getName());
                        //再把压缩后的bitmap保存到本地
                        File fileCompressed = BitmapManager.saveFile(base64AndFileBean.getBitmapCompressed(), base64AndFileBean.getDirsPathCompressed(), "picture_large_compressed.png");
                        base64AndFileBean.setFileCompressed(fileCompressed);
                        LogManager.i(TAG, "base64AndFileBean.getFileCompressed().getPath()*****" + base64AndFileBean.getFileCompressed().getPath());
                        LogManager.i(TAG, "base64AndFileBean.getFileCompressed().getAbsolutePath()*****" + base64AndFileBean.getFileCompressed().getAbsolutePath());
                    }
                })
                .observeOn(Schedulers.io()) //给下面分配了异步线程
                .doOnNext(new Consumer() {
                    @Override
                    public void accept(Base64AndFileBean base64AndFileBean) throws Exception {
                        LogManager.i(TAG, "threadName7*****" + Thread.currentThread().getName());
                        String base64Str = null;
                        if (base64AndFileBean.getFileCompressed().exists()) {
                            base64Str = Base64AndFileManager.fileToBase64(base64AndFileBean.getFileCompressed());
//                base64Str = Base64AndFileManager.fileToBase64Test(file);
//                    base64Str = Base64AndFileManager.fileToBase64Second(file);
                            base64AndFileBean.setBase64Str(base64Str);
                        }
                        if (!TextUtils.isEmpty(base64Str)) {
                            String fileName = "base64Str.txt";
                            String txtFilePath = FileManager.writeStrToTextFile(base64Str, base64AndFileBean.getDirsPathCompressed(), fileName);
                            base64AndFileBean.setTxtFilePath(txtFilePath);
                            base64AndFileBean.setBase64StrList(Base64AndFileManager.getBase64StrList(txtFilePath));
//                base64Str = "";
//                StringBuilder stringBuilder = new StringBuilder();
//                for (int i = 0; i < base64StrList.size(); i++) {
//                    stringBuilder.append(base64StrList.get(i));
//                }
//                base64Str = stringBuilder.toString();

//                    //把字符串的最後一個打印出來,然後看看和RecyclerView顯示的最後一個字符串是否一致
//                    LogManager.i(TAG, "base64StrList******" + base64StrList.get(base64StrList.size() - 1));
                        }
                    }
                })
                .observeOn(AndroidSchedulers.mainThread()) //给下面分配了异步线程
                .doOnNext(new Consumer() {
                    @Override
                    public void accept(Base64AndFileBean base64AndFileBean) throws Exception {
                        LogManager.i(TAG, "threadName8*****" + Thread.currentThread().getName());
                        tevPictureToBase64.setVisibility(View.GONE);
                        rcvBase64Str.setVisibility(View.VISIBLE);

                        base64StrAdapter.clearData();
                        base64StrAdapter.addAllData(base64AndFileBean.getBase64StrList());

                        Observable.timer(2000, TimeUnit.MILLISECONDS)
                                .subscribeOn(Schedulers.io())
                                .observeOn(AndroidSchedulers.mainThread())
                                //解决RxJava2导致的内存泄漏问题
                                .compose(bindUntilEvent(ActivityEvent.DESTROY))
                                .subscribe(new Consumer() {
                                    @Override
                                    public void accept(Long aLong) throws Exception {
                                        LogManager.i(TAG, "threadNameC*****" + Thread.currentThread().getName());
                                        if (base64AndFileBean.getBase64StrList().size() > 0) {
                                            //RecyclerView自動滑動到底部,看看最後一個字符串和打印出來的字符串是否一致
                                            rcvBase64Str.scrollToPosition(base64AndFileBean.getBase64StrList().size() - 1);
                                        }
                                    }
                                });
                    }
                })
                .observeOn(Schedulers.io()) //给下面分配了异步线程
                .doOnNext(new Consumer() {
                    @Override
                    public void accept(Base64AndFileBean base64AndFileBean) throws Exception {
                        LogManager.i(TAG, "threadName9*****" + Thread.currentThread().getName());
                        //再把压缩后的bitmap保存到本地
                        File fileCompressedRecover = Base64AndFileManager.base64ToFile(base64AndFileBean.getBase64Str(),
                                base64AndFileBean.getDirsPathCompressedRecover(),
                                "picture_large_compressed_recover");
                        base64AndFileBean.setFileCompressedRecover(fileCompressedRecover);
                    }
                })
                .observeOn(Schedulers.io()) //给下面分配了异步线程
//                .doOnNext(new Consumer() {
//                    @Override
//                    public void accept(Base64AndFileBean base64AndFileBean) throws Exception {
//                        LogManager.i(TAG, "threadName10*****" + Thread.currentThread().getName());
//                        Bitmap bitmapCompressedRecover = BitmapFactory.decodeFile(base64AndFileBean.getFileCompressedRecover().getAbsolutePath());
//                        base64AndFileBean.setBitmapCompressedRecover(bitmapCompressedRecover);
//                    }
//                })
                .map(new Function() {
                    @Override
                    public Bitmap apply(Base64AndFileBean base64AndFileBean) throws Exception {
                        LogManager.i(TAG, "threadName10*****" + Thread.currentThread().getName());
                        Bitmap bitmapCompressedRecover = BitmapFactory.decodeFile(base64AndFileBean.getFileCompressedRecover().getAbsolutePath());
                        return bitmapCompressedRecover;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread()) //给下面分配了UI线程
                //解决RxJava2导致的内存泄漏问题
                .compose(bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Bitmap bitmapCompressedRecover) throws Exception {
                        LogManager.i(TAG, "threadName11*****" + Thread.currentThread().getName());
                        tevBase64ToPicture.setVisibility(View.GONE);
                        imvBase64ToPicture.setVisibility(View.VISIBLE);
                        imvBase64ToPicture.setImageBitmap(bitmapCompressedRecover);
                        base64AndFileBean.setBitmapCompressedRecover(bitmapCompressedRecover);
                        hideLoading();
                    }
                });

    }

6.基础Activity文件。

package com.phone.common_library.base;

import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.os.Looper;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;

import com.gyf.immersionbar.ImmersionBar;
import com.phone.common_library.BaseApplication;
import com.phone.common_library.R;
import com.phone.common_library.manager.ActivityPageManager;
import com.phone.common_library.manager.CrashHandlerManager;
import com.phone.common_library.manager.LogManager;
import com.phone.common_library.manager.ToolbarManager;
import com.qmuiteam.qmui.widget.QMUILoadingView;
import com.trello.rxlifecycle3.components.support.RxAppCompatActivity;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class BaseMvpRxAppActivity> extends RxAppCompatActivity {

    private static final String TAG = "BaseMvpRxAppActivity";
    public QMUILoadingView loadView;
    protected FrameLayout.LayoutParams layoutParams;

    protected T presenter;

    protected String url;
    protected Map bodyParams = new HashMap<>();
    protected Intent intent;
    protected Bundle bundle;
    protected RxAppCompatActivity rxAppCompatActivity;
    protected BaseApplication baseApplication;
    public ActivityPageManager activityPageManager;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        rxAppCompatActivity = this;
        baseApplication = (BaseApplication) getApplication();
        activityPageManager = ActivityPageManager.getInstance();
        activityPageManager.addActivity(this);

        setContentView(initLayoutId());

        loadView = new QMUILoadingView(this);
        loadView.setVisibility(View.GONE);
        loadView.setSize(100);
        loadView.setColor(getResources().getColor(R.color.color_80000000));
        layoutParams = new FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
        layoutParams.gravity = Gravity.CENTER;

        //        setToolbar();
        presenter = attachPresenter();
        initData();
        initViews();
        initLoadData();

//        RxPermissionsManager rxPermissionsManager = RxPermissionsManager.getInstance(this);
//        rxPermissionsManager.initRxPermissionsActivity(new OnCommonRxPermissionsCallback() {
//            @Override
//            public void onRxPermissionsAllPass() {
//                CrashHandlerManager crashHandlerManager = CrashHandlerManager.getInstance(rxAppCompatActivity);
//                crashHandlerManager.sendPreviousReportsToServer();
//                crashHandlerManager.init();
//            }
//
//            @Override
//            public void onNotCheckNoMorePromptError() {
//
//            }
//
//            @Override
//            public void onCheckNoMorePromptError() {
//
//            }
//        });
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        //非默认值
        if (newConfig.fontScale != 1) {
            getResources();
        }
        super.onConfigurationChanged(newConfig);
    }

    @Override
    public Resources getResources() {//还原字体大小
        Resources res = super.getResources();
        //非默认值
        if (res.getConfiguration().fontScale != 1) {
            Configuration newConfig = new Configuration();
            newConfig.setToDefaults();//设置默认
            res.updateConfiguration(newConfig, res.getDisplayMetrics());
        }
        return res;
    }

    protected abstract int initLayoutId();

    protected void setToolbar(boolean isDarkFont) {
        if (isDarkFont) {
            ImmersionBar.with(this) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
                    .statusBarDarkFont(isDarkFont)
                    .statusBarColor(R.color.color_FFFFFFFF)     //状态栏颜色,不写默认透明色
                    //                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
                    .keyboardEnable(true)
                    .init();
        } else {
            ImmersionBar.with(this)
                    .statusBarDarkFont(isDarkFont)
                    .statusBarColor(R.color.color_FF198CFF)     //状态栏颜色,不写默认透明色
                    //                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
                    .keyboardEnable(true)
                    .init();
        }

        ToolbarManager.assistActivity(findViewById(android.R.id.content));
    }

    protected void setToolbar(boolean isDarkFont, boolean isResizeChildOfContent) {
        if (isDarkFont) {
            ImmersionBar.with(this) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
                    .statusBarDarkFont(isDarkFont)
                    .statusBarColor(R.color.color_FFFFFFFF)     //状态栏颜色,不写默认透明色
                    //                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
                    .keyboardEnable(true)
                    .init();
        } else {
            ImmersionBar.with(this)
                    .statusBarDarkFont(isDarkFont)
                    .statusBarColor(R.color.color_FF198CFF)     //状态栏颜色,不写默认透明色
                    //                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
                    .keyboardEnable(true)
                    .init();
        }

        if (isResizeChildOfContent) {
            ToolbarManager.assistActivity(findViewById(android.R.id.content));
        }
    }

    protected void setToolbar(boolean isDarkFont, int color) {
        if (isDarkFont) {
            ImmersionBar.with(this) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
                    .statusBarDarkFont(isDarkFont)
                    .statusBarColor(color)     //状态栏颜色,不写默认透明色
                    //                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
                    .init();
        } else {
            ImmersionBar.with(this)
                    .statusBarDarkFont(isDarkFont)
                    .statusBarColor(color)     //状态栏颜色,不写默认透明色
                    //                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
                    .init();
        }

        ToolbarManager.assistActivity(findViewById(android.R.id.content));
    }

    protected void setToolbar(boolean isDarkFont, int color, boolean isResizeChildOfContent) {
        if (isDarkFont) {
            ImmersionBar.with(this) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
                    .statusBarDarkFont(isDarkFont)
                    .statusBarColor(color)     //状态栏颜色,不写默认透明色
                    //                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
                    .init();
        } else {
            ImmersionBar.with(this)
                    .statusBarDarkFont(isDarkFont)
                    .statusBarColor(color)     //状态栏颜色,不写默认透明色
                    //                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
                    .init();
        }

        if (isResizeChildOfContent) {
            ToolbarManager.assistActivity(findViewById(android.R.id.content));
        }
    }

    
    protected void initImmersionBar() {
        //设置共同沉浸式样式
        ImmersionBar.with(this)
                .navigationBarColor(R.color.color_FFE066FF).init();
    }

    protected abstract void initData();

    protected abstract void initViews();

    protected abstract void initLoadData();

    
    protected abstract T attachPresenter();

    protected void showToast(String message, boolean isLongToast) {
        //        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
        if (!rxAppCompatActivity.isFinishing()) {
            Toast toast;
            int duration;
            if (isLongToast) {
                duration = Toast.LENGTH_LONG;
            } else {
                duration = Toast.LENGTH_SHORT;
            }
            toast = Toast.makeText(rxAppCompatActivity, message, duration);
            toast.setGravity(Gravity.CENTER, 0, 0);
            toast.show();
        }
    }

    protected void showCustomToast(int left, int right,
                                   int textSize, int textColor,
                                   int bgColor, int height,
                                   int roundRadius, String message,
                                   boolean isLongToast) {
        FrameLayout frameLayout = new FrameLayout(this);
        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
        frameLayout.setLayoutParams(layoutParams);
        TextView textView = new TextView(this);
        FrameLayout.LayoutParams layoutParams1 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, height);
        textView.setLayoutParams(layoutParams1);
        textView.setPadding(left, 0, right, 0);
        textView.setTextSize(textSize);
        textView.setTextColor(textColor);
        textView.setGravity(Gravity.CENTER);
        textView.setIncludeFontPadding(false);
        GradientDrawable gradientDrawable = new GradientDrawable();//创建drawable
        gradientDrawable.setColor(bgColor);
        gradientDrawable.setCornerRadius(roundRadius);
        textView.setBackground(gradientDrawable);
        textView.setText(message);
        frameLayout.addView(textView);

        Toast toast = new Toast(this);
        toast.setView(frameLayout);
        if (isLongToast) {
            toast.setDuration(Toast.LENGTH_LONG);
        } else {
            toast.setDuration(Toast.LENGTH_SHORT);
        }
        toast.show();
    }

    public boolean isOnMainThread() {
        return Looper.getMainLooper().getThread().getId() == Thread.currentThread().getId();
    }

    protected void startActivity(Class cls) {
        intent = new Intent(this, cls);
        startActivity(intent);
    }

    protected void startActivityCarryParams(Class cls, Map params) {
        intent = new Intent(this, cls);
        bundle = new Bundle();

        if (params != null && params.size() > 0) {
            for (String key : params.keySet()) {
                if (params.get(key) != null) {//如果参数不是null,才把参数传给后台
                    bundle.putString(key, params.get(key));
                }
            }
            intent.putExtras(bundle);
        }
        startActivity(intent);
    }

    protected void startActivityForResult(Class cls, int requestCode) {
        intent = new Intent(this, cls);
        startActivityForResult(intent, requestCode);
    }

    protected void startActivityForResultCarryParams(Class cls, Map params, int requestCode) {
        intent = new Intent(this, cls);
        bundle = new Bundle();

        if (params != null && params.size() > 0) {
            for (String key : params.keySet()) {
                if (params.get(key) != null) {//如果参数不是null,才把参数传给后台
                    bundle.putString(key, params.get(key));
                }
            }
            intent.putExtras(bundle);
        }
        startActivityForResult(intent, requestCode);
    }

    protected boolean isEmpty(String dataStr) {
        if (dataStr != null && !"".equals(dataStr)) {
            return false;
        } else {
            return true;
        }
    }

    protected void detachPresenter() {
        if (presenter != null) {
            presenter.detachView();
            presenter = null;
        }
    }

    private void killAppProcess(Context context) {
        LogManager.i(TAG, "killAppProcess");
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List processInfos = manager.getRunningAppProcesses();
        // 先杀掉相关进程,最后再杀掉主进程
        for (ActivityManager.RunningAppProcessInfo runningAppProcessInfo : processInfos) {
            if (runningAppProcessInfo.pid != android.os.Process.myPid()) {
                android.os.Process.killProcess(runningAppProcessInfo.pid);
            }
        }

        LogManager.i(TAG, "执行killAppProcess,應用開始自殺");
        CrashHandlerManager crashHandlerManager = CrashHandlerManager.getInstance(context);
        crashHandlerManager.saveTrimMemoryInfoToFile("执行killAppProcess,應用開始自殺");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            LogManager.i(TAG, "error");
        }

        android.os.Process.killProcess(android.os.Process.myPid());
        // 正常退出程序,也就是结束当前正在运行的 java 虚拟机
        System.exit(0);
    }

    @Override
    protected void onDestroy() {
        detachPresenter();
        if (bodyParams != null) {
            bodyParams.clear();
            bodyParams = null;
        }
        if (activityPageManager != null) {
            if (activityPageManager.isLastAliveActivity().get()) {
                killAppProcess(baseApplication);
            }
            activityPageManager.removeActivity(rxAppCompatActivity);
        }
        super.onDestroy();
    }
}

7.Activity文件。

package com.phone.base64_and_file;

import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.phone.base64_and_file.adapter.Base64StrAdapter;
import com.phone.base64_and_file.bean.Base64AndFileBean;
import com.phone.base64_and_file.presenter.Base64AndFilePresenterImpl;
import com.phone.common_library.base.BaseMvpRxAppActivity;
import com.phone.common_library.base.IBaseView;
import com.phone.common_library.callback.OnCommonRxPermissionsCallback;
import com.phone.common_library.manager.LogManager;
import com.phone.common_library.manager.RxPermissionsManager;
import com.phone.common_library.manager.SystemManager;
import com.qmuiteam.qmui.widget.QMUILoadingView;
import com.trello.rxlifecycle3.android.ActivityEvent;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

public class Base64AndFileActivity extends BaseMvpRxAppActivity implements IBase64AndFileView {

    private static final String TAG = Base64AndFileActivity.class.getSimpleName();
    private Toolbar toolbar;
    private TextView tevTitle;
    private TextView tevRequestPermissions;
    private TextView tevCompressedPicture;
    private ImageView imvCompressedPicture;
    private TextView tevPictureToBase64;
    private RecyclerView rcvBase64Str;
    private TextView tevBase64ToPicture;
    private ImageView imvBase64ToPicture;
    private TextView tevResetData;
    private QMUILoadingView loadView;


    // where this is an Activity or Fragment instance
    //    private Binder binder;
    private String dirsPath;
    private String dirsPathCompressed;
    private String dirsPathCompressedRecover;

    private List base64StrList = new ArrayList<>();
    private LinearLayoutManager linearLayoutManager;
    private Base64StrAdapter base64StrAdapter;

    private Timer timer;
    private TimerTask timerTask;
    private Handler handler;

    private AlertDialog mPermissionsDialog;
    private Base64AndFileBean base64AndFileBean;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected int initLayoutId() {
        return R.layout.activity_base64_and_file;
    }

    @Override
    protected void initData() {
        dirsPath = Environment.getExternalStorageDirectory().getAbsolutePath()
                + File.separator + "Pictures";
        dirsPathCompressed = Environment.getExternalStorageDirectory().getAbsolutePath()
                + File.separator + "PicturesCompressed";
        dirsPathCompressedRecover = Environment.getExternalStorageDirectory().getAbsolutePath()
                + File.separator + "PicturesCompressedRecover";
        base64AndFileBean = new Base64AndFileBean();
        base64AndFileBean.setDirsPath(dirsPath);
        base64AndFileBean.setDirsPathCompressed(dirsPathCompressed);
        base64AndFileBean.setDirsPathCompressedRecover(dirsPathCompressedRecover);

        handler = new Handler(Looper.getMainLooper());
    }

    @Override
    protected void initViews() {
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        tevTitle = (TextView) findViewById(R.id.tev_title);
        tevRequestPermissions = (TextView) findViewById(R.id.tev_request_permissions);
        tevCompressedPicture = (TextView) findViewById(R.id.tev_compressed_picture);
        imvCompressedPicture = (ImageView) findViewById(R.id.imv_compressed_picture);
        tevPictureToBase64 = (TextView) findViewById(R.id.tev_picture_to_base64);
        rcvBase64Str = (RecyclerView) findViewById(R.id.rcv_base64_str);
        tevBase64ToPicture = (TextView) findViewById(R.id.tev_base64_to_picture);
        imvBase64ToPicture = (ImageView) findViewById(R.id.imv_base64_to_picture);
        tevResetData = (TextView) findViewById(R.id.tev_reset_data);
        loadView = (QMUILoadingView) findViewById(R.id.load_view);

        setToolbar(false, R.color.color_54E066FF);

        tevRequestPermissions.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LogManager.i(TAG, "tevRequestPermissions");
                initRxPermissionsRxAppCompatActivity();
            }
        });
//        tevCompressedPicture.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                initRxPermissionsRxAppCompatActivity();
//            }
//        });
//        tevPictureToBase64.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                if (presenter != null) {
//                    showLoading();
//                    presenter.showPictureToBase64(compressedPicturePath);
//                }
//            }
//        });
//        tevBase64ToPicture.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                if (presenter != null) {
//                    showLoading();
//                    presenter.showBase64ToPicture(compressedPicturePath, base64Str);
//                }
//            }
//        });
        tevResetData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                resetData();
            }
        });

        initAdapter();
    }

    private void initAdapter() {
        linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(RecyclerView.VERTICAL);
        rcvBase64Str.setLayoutManager(linearLayoutManager);
        rcvBase64Str.setItemAnimator(new DefaultItemAnimator());

        base64StrAdapter = new Base64StrAdapter(this);
        rcvBase64Str.setAdapter(base64StrAdapter);
        base64StrAdapter.clearData();
        base64StrAdapter.addAllData(base64StrList);
    }

    @Override
    protected void initLoadData() {
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//            initRxPermissions();
//        } else {
//
            Intent bindIntent = new Intent(this, Base64AndFileService.class);
            // 绑定服务和活动,之后活动就可以去调服务的方法了
            bindService(bindIntent, connection, BIND_AUTO_CREATE);
//        }


    }

    @Override
    protected Base64AndFilePresenterImpl attachPresenter() {
        return new Base64AndFilePresenterImpl(this);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {

        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 207) {
//            initRxPermissions();
        }
    }

    private void showSystemSetupDialog() {
        cancelPermissionsDialog();
        if (mPermissionsDialog == null) {
            mPermissionsDialog = new AlertDialog.Builder(this)
                    .setTitle("权限设置")
                    .setMessage("获取相关权限失败,将导致部分功能无法正常使用,请到设置页面手动授权")
                    .setPositiveButton("去授权", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            cancelPermissionsDialog();
                            intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                            Uri uri = Uri.fromParts("package", getApplicationContext().getPackageName(), null);
                            intent.setData(uri);
                            startActivityForResult(intent, 207);
                        }
                    })
                    .create();
        }

        mPermissionsDialog.setCancelable(false);
        mPermissionsDialog.setCanceledOnTouchOutside(false);
        mPermissionsDialog.show();
    }

    
    private void cancelPermissionsDialog() {
        if (mPermissionsDialog != null) {
            mPermissionsDialog.cancel();
            mPermissionsDialog = null;
        }
    }

    
    private void initRxPermissionsRxAppCompatActivity() {
        RxPermissionsManager rxPermissionsManager = new RxPermissionsManager();
        rxPermissionsManager.initRxPermissionsRxAppCompatActivity(this, new OnCommonRxPermissionsCallback() {
            @Override
            public void onRxPermissionsAllPass() {
                if (TextUtils.isEmpty(baseApplication.getSystemId())) {
                    String systemId = SystemManager.getSystemId(baseApplication);
                    baseApplication.setSystemId(systemId);
                    LogManager.i(TAG, "isEmpty systemId*****" + baseApplication.getSystemId());
                } else {
                    LogManager.i(TAG, "systemId*****" + baseApplication.getSystemId());
                }

//                //第一种方法
//                if (presenter != null) {
//                    showLoading();
//
//                    presenter.showCompressedPicture(baseApplication,
//                            base64AndFileBean);
//                }


                //第二种方法
                initBase64AndFileTask();
            }

            @Override
            public void onNotCheckNoMorePromptError() {
                showSystemSetupDialog();
            }

            @Override
            public void onCheckNoMorePromptError() {
                showSystemSetupDialog();
            }
        });
    }

    
    private void initBase64AndFileTask() {
        Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter emitter) throws Exception {
                LogManager.i(TAG, "threadName*****" + Thread.currentThread().getName());
                showLoading();
                emitter.onNext(0);
            }
        }).subscribeOn(AndroidSchedulers.mainThread()) //给上面分配了UI线程
//                .observeOn(AndroidSchedulers.mainThread()) //给下面分配了UI线程
//                .doOnNext(new Consumer() {
//                    @Override
//                    public void accept(Integer integer) throws Exception {
//                        LogManager.i(TAG, "threadName*****" + Thread.currentThread().getName());
//                        showLoading();
//                    }
//                })
                .observeOn(Schedulers.io()) //给下面分配了异步线程
                .map(new Function() {
                    @Override
                    public Base64AndFileBean apply(Integer integer) throws Exception {
                        LogManager.i(TAG, "threadName2*****" + Thread.currentThread().getName());
                        File file = BitmapManager.getAssetFile(baseApplication, dirsPath, "picture_large.png");
                        base64AndFileBean.setFile(file);
                        return base64AndFileBean;
                    }
                })
                .observeOn(Schedulers.io()) //给下面分配了异步线程
                .doOnNext(new Consumer() {
                    @Override
                    public void accept(Base64AndFileBean base64AndFileBean) throws Exception {
                        LogManager.i(TAG, "threadName3*****" + Thread.currentThread().getName());
                        //把图片转化成bitmap
                        Bitmap bitmap = BitmapManager.getBitmap(base64AndFileBean.getFile().getAbsolutePath());
                        base64AndFileBean.setBitmap(bitmap);
                    }
                })
                .observeOn(Schedulers.io()) //给下面分配了异步线程
                .doOnNext(new Consumer() {
                    @Override
                    public void accept(Base64AndFileBean base64AndFileBean) throws Exception {
                        LogManager.i(TAG, "threadName4*****" + Thread.currentThread().getName());
                        //再压缩bitmap
                        Bitmap bitmapCompressed = BitmapManager.scaleImage(base64AndFileBean.getBitmap(), 1280, 960);
                        base64AndFileBean.setBitmapCompressed(bitmapCompressed);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread()) //给下面分配了异步线程
                .doOnNext(new Consumer() {
                    @Override
                    public void accept(Base64AndFileBean base64AndFileBean) throws Exception {
                        LogManager.i(TAG, "threadName5*****" + Thread.currentThread().getName());
                        //展示压缩过的图片
                        tevCompressedPicture.setVisibility(View.GONE);
                        imvCompressedPicture.setVisibility(View.VISIBLE);
                        imvCompressedPicture.setImageBitmap(base64AndFileBean.getBitmapCompressed());
                    }
                })
                .observeOn(Schedulers.io()) //给下面分配了异步线程
                .doOnNext(new Consumer() {
                    @Override
                    public void accept(Base64AndFileBean base64AndFileBean) throws Exception {
                        LogManager.i(TAG, "threadName6*****" + Thread.currentThread().getName());
                        //再把压缩后的bitmap保存到本地
                        File fileCompressed = BitmapManager.saveFile(base64AndFileBean.getBitmapCompressed(), base64AndFileBean.getDirsPathCompressed(), "picture_large_compressed.png");
                        base64AndFileBean.setFileCompressed(fileCompressed);
                        LogManager.i(TAG, "base64AndFileBean.getFileCompressed().getPath()*****" + base64AndFileBean.getFileCompressed().getPath());
                        LogManager.i(TAG, "base64AndFileBean.getFileCompressed().getAbsolutePath()*****" + base64AndFileBean.getFileCompressed().getAbsolutePath());
                    }
                })
                .observeOn(Schedulers.io()) //给下面分配了异步线程
                .doOnNext(new Consumer() {
                    @Override
                    public void accept(Base64AndFileBean base64AndFileBean) throws Exception {
                        LogManager.i(TAG, "threadName7*****" + Thread.currentThread().getName());
                        String base64Str = null;
                        if (base64AndFileBean.getFileCompressed().exists()) {
                            base64Str = Base64AndFileManager.fileToBase64(base64AndFileBean.getFileCompressed());
//                base64Str = Base64AndFileManager.fileToBase64Test(file);
//                    base64Str = Base64AndFileManager.fileToBase64Second(file);
                            base64AndFileBean.setBase64Str(base64Str);
                        }
                        if (!TextUtils.isEmpty(base64Str)) {
                            String fileName = "base64Str.txt";
                            String txtFilePath = FileManager.writeStrToTextFile(base64Str, base64AndFileBean.getDirsPathCompressed(), fileName);
                            base64AndFileBean.setTxtFilePath(txtFilePath);
                            base64AndFileBean.setBase64StrList(Base64AndFileManager.getBase64StrList(txtFilePath));
//                base64Str = "";
//                StringBuilder stringBuilder = new StringBuilder();
//                for (int i = 0; i < base64StrList.size(); i++) {
//                    stringBuilder.append(base64StrList.get(i));
//                }
//                base64Str = stringBuilder.toString();

//                    //把字符串的最後一個打印出來,然後看看和RecyclerView顯示的最後一個字符串是否一致
//                    LogManager.i(TAG, "base64StrList******" + base64StrList.get(base64StrList.size() - 1));
                        }
                    }
                })
                .observeOn(AndroidSchedulers.mainThread()) //给下面分配了异步线程
                .doOnNext(new Consumer() {
                    @Override
                    public void accept(Base64AndFileBean base64AndFileBean) throws Exception {
                        LogManager.i(TAG, "threadName8*****" + Thread.currentThread().getName());
                        tevPictureToBase64.setVisibility(View.GONE);
                        rcvBase64Str.setVisibility(View.VISIBLE);

                        base64StrAdapter.clearData();
                        base64StrAdapter.addAllData(base64AndFileBean.getBase64StrList());

                        Observable.timer(2000, TimeUnit.MILLISECONDS)
                                .subscribeOn(Schedulers.io())
                                .observeOn(AndroidSchedulers.mainThread())
                                //解决RxJava2导致的内存泄漏问题
                                .compose(bindUntilEvent(ActivityEvent.DESTROY))
                                .subscribe(new Consumer() {
                                    @Override
                                    public void accept(Long aLong) throws Exception {
                                        LogManager.i(TAG, "threadNameC*****" + Thread.currentThread().getName());
                                        if (base64AndFileBean.getBase64StrList().size() > 0) {
                                            //RecyclerView自動滑動到底部,看看最後一個字符串和打印出來的字符串是否一致
                                            rcvBase64Str.scrollToPosition(base64AndFileBean.getBase64StrList().size() - 1);
                                        }
                                    }
                                });
                    }
                })
                .observeOn(Schedulers.io()) //给下面分配了异步线程
                .doOnNext(new Consumer() {
                    @Override
                    public void accept(Base64AndFileBean base64AndFileBean) throws Exception {
                        LogManager.i(TAG, "threadName9*****" + Thread.currentThread().getName());
                        //再把压缩后的bitmap保存到本地
                        File fileCompressedRecover = Base64AndFileManager.base64ToFile(base64AndFileBean.getBase64Str(),
                                base64AndFileBean.getDirsPathCompressedRecover(),
                                "picture_large_compressed_recover");
                        base64AndFileBean.setFileCompressedRecover(fileCompressedRecover);
                    }
                })
                .observeOn(Schedulers.io()) //给下面分配了异步线程
//                .doOnNext(new Consumer() {
//                    @Override
//                    public void accept(Base64AndFileBean base64AndFileBean) throws Exception {
//                        LogManager.i(TAG, "threadName10*****" + Thread.currentThread().getName());
//                        Bitmap bitmapCompressedRecover = BitmapFactory.decodeFile(base64AndFileBean.getFileCompressedRecover().getAbsolutePath());
//                        base64AndFileBean.setBitmapCompressedRecover(bitmapCompressedRecover);
//                    }
//                })
                .map(new Function() {
                    @Override
                    public Bitmap apply(Base64AndFileBean base64AndFileBean) throws Exception {
                        LogManager.i(TAG, "threadName10*****" + Thread.currentThread().getName());
                        Bitmap bitmapCompressedRecover = BitmapFactory.decodeFile(base64AndFileBean.getFileCompressedRecover().getAbsolutePath());
                        return bitmapCompressedRecover;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread()) //给下面分配了UI线程
                //解决RxJava2导致的内存泄漏问题
                .compose(bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Bitmap bitmapCompressedRecover) throws Exception {
                        LogManager.i(TAG, "threadName11*****" + Thread.currentThread().getName());
                        tevBase64ToPicture.setVisibility(View.GONE);
                        imvBase64ToPicture.setVisibility(View.VISIBLE);
                        imvBase64ToPicture.setImageBitmap(bitmapCompressedRecover);
                        base64AndFileBean.setBitmapCompressedRecover(bitmapCompressedRecover);
                        hideLoading();
                    }
                });

    }

    @Override
    public void showLoading() {
        if (loadView != null && !loadView.isShown()) {
            loadView.setVisibility(View.VISIBLE);
            loadView.start();
        }
    }

    @Override
    public void hideLoading() {
        if (loadView != null && loadView.isShown()) {
            loadView.stop();
            loadView.setVisibility(View.GONE);
        }
    }

//    private ServiceConnection connection = new ServiceConnection() {
//
//        
//        @Override
//        public void onServiceDisconnected(ComponentName name) {
//        }
//
//        
//        @Override
//        public void onServiceConnected(ComponentName name, IBinder service) {
//            taskBinder = (TaskBinder) service;
//        }
//    };

//    private Base64AndFileServiceConnection connection = new Base64AndFileServiceConnection(new OnCommonSingleParamCallback() {
//        @Override
//        public void onSuccess(Binder success) {
//            binder = success;
//        }
//
//        @Override
//        public void onError(String error) {
//
//        }
//    });

    private void startTimer() {
        stopTimer();
        if (timer == null) {
            timer = new Timer();
        }

        if (timerTask == null) {
            timerTask = new TimerTask() {
                @Override
                public void run() {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (base64StrList.size() > 0) {
                                //RecyclerView自動滑動到底部,看看最後一個字符串和打印出來的字符串是否一致
                                rcvBase64Str.scrollToPosition(base64StrList.size() - 1);
                            }
                        }
                    });
                }
            };
        }

        if (timer != null && timerTask != null) {
            timer.schedule(timerTask, 500);
        }
    }

    private void stopTimer() {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }

        if (timerTask != null) {
            timerTask.cancel();
            timerTask = null;
        }
    }

    @Override
    public void showCompressedPictureSuccess(Base64AndFileBean success) {
        base64AndFileBean = success;
        tevCompressedPicture.setVisibility(View.GONE);
        imvCompressedPicture.setVisibility(View.VISIBLE);
        imvCompressedPicture.setImageBitmap(base64AndFileBean.getBitmapCompressed());
        hideLoading();
        LogManager.i(TAG, "showCompressedPictureSuccess");

        if (presenter != null) {
            showLoading();
            presenter.showPictureToBase64(base64AndFileBean);
        }
    }

    @Override
    public void showCompressedPictureError(String error) {
        hideLoading();
        Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showPictureToBase64Success(Base64AndFileBean success) {
        base64AndFileBean = success;
        tevPictureToBase64.setVisibility(View.GONE);

        rcvBase64Str.setVisibility(View.VISIBLE);
        this.base64StrList.clear();
        this.base64StrList.addAll(base64AndFileBean.getBase64StrList());
        base64StrAdapter.clearData();
        base64StrAdapter.addAllData(this.base64StrList);
        hideLoading();
        startTimer();

        if (presenter != null) {
            showLoading();
            presenter.showBase64ToPicture(success);
        }
    }

    @Override
    public void showPictureToBase64Error(String error) {
        hideLoading();
        Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showBase64ToPictureSuccess(Base64AndFileBean success) {
        base64AndFileBean = success;
        tevBase64ToPicture.setVisibility(View.GONE);
        imvBase64ToPicture.setVisibility(View.VISIBLE);
        imvBase64ToPicture.setImageBitmap(success.getBitmap());
        hideLoading();
    }

    @Override
    public void showBase64ToPictureError(String error) {
        hideLoading();
        Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
        resetData();
    }

    private void resetData() {
        if (base64AndFileBean.getBitmap() != null && !base64AndFileBean.getBitmap().isRecycled()) {
            base64AndFileBean.getBitmap().recycle();
            base64AndFileBean.setBitmap(null);
        }
        if (base64AndFileBean.getBitmapCompressed() != null && !base64AndFileBean.getBitmapCompressed().isRecycled()) {
            base64AndFileBean.getBitmapCompressed().recycle();
            base64AndFileBean.setBitmapCompressed(null);
        }
        if (base64AndFileBean.getBitmapCompressedRecover() != null && !base64AndFileBean.getBitmapCompressedRecover().isRecycled()) {
            base64AndFileBean.getBitmapCompressedRecover().recycle();
            base64AndFileBean.setBitmapCompressedRecover(null);
        }


        tevCompressedPicture.setVisibility(View.VISIBLE);
        imvCompressedPicture.setVisibility(View.GONE);
        tevPictureToBase64.setVisibility(View.VISIBLE);
        if (base64StrList.size() > 0) {
            rcvBase64Str.scrollToPosition(0);
            base64StrList.clear();
            base64StrAdapter.clearData();
        }
        rcvBase64Str.setVisibility(View.GONE);
        tevBase64ToPicture.setVisibility(View.VISIBLE);
        imvBase64ToPicture.setVisibility(View.GONE);
    }

    @Override
    protected void onDestroy() {
        stopTimer();
        if (base64AndFileBean.getBitmap() != null && !base64AndFileBean.getBitmap().isRecycled()) {
            base64AndFileBean.getBitmap().recycle();
            base64AndFileBean.setBitmap(null);
        }
        if (base64AndFileBean.getBitmapCompressed() != null && !base64AndFileBean.getBitmapCompressed().isRecycled()) {
            base64AndFileBean.getBitmapCompressed().recycle();
            base64AndFileBean.setBitmapCompressed(null);
        }
        if (base64AndFileBean.getBitmapCompressedRecover() != null && !base64AndFileBean.getBitmapCompressedRecover().isRecycled()) {
            base64AndFileBean.getBitmapCompressedRecover().recycle();
            base64AndFileBean.setBitmapCompressedRecover(null);
        }
//        if (connection != null) {
//            // 解绑服务,服务要记得解绑,不要造成内存泄漏
//            unbindService(connection);
//            binder = null;
//        }
        super.onDestroy();
    }
}

8.Activity的layout文件。




    

        

            

        

        

        

            

                

                

            

            

            

                

                

            

            

            

                

                

            

            

            

        


    

    

9.values下的string的xml文件。

    Base64AndFile
    請求權限

如对此有疑问,请联系qq1164688204。

推荐Android开源项目

项目功能介绍:RxJava2和Retrofit2项目,添加自动管理token功能,添加RxJava2生命周期管理,使用App架构设计是MVP模式和MVVM模式,同时使用组件化,部分代码使用Kotlin,此项目持续维护中。

项目地址:https://gitee.com/urasaki/RxJava2AndRetrofit2

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/946240.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号