2021SC@SDUSC Zxing开源代码(十三)EncodeActivity 代码分析

文章目录

  • 前言
  • 代码分析
      • QRCodeEncoder 构造函数
      • QRCodeEncoder.encodeAsBitmap
  • 总结


前言

在前面的博客分析了当在主页面点击“创建二维码”后,所进入的页面 ShareActivity 。其作为 EncodeActivity 的入口,将具体对文字进行的编码操作都放到了 EncodeActivity 中进行,本次代码就重点分析 EncodeActivity 的内容,来解析编码流程。


代码分析

EncodeActivity 作为 Activity 的子类,进入后首先执行的还是生命周期函数,在 onCreate 方法中,加载了布局文件。而执行到 onResume 方法后,有:

      qrCodeEncoder = new QRCodeEncoder(this, intent, smallerDimension, useVCard);
      Bitmap bitmap = qrCodeEncoder.encodeAsBitmap();

可知其创建了 QRCodeEncoder 对象,调用方法 Bitmap bitmap = qrCodeEncoder.encodeAsBitmap()来得到对应的比特位图。下面首先看一下 QRCodeEncoder 的相关代码:

QRCodeEncoder 构造函数

  QRCodeEncoder(Context activity, Intent intent, int dimension, boolean useVCard) throws WriterException {
    this.activity = activity;
    this.dimension = dimension;
    this.useVCard = useVCard;
    String action = intent.getAction();
    // 如果传递的意图来自 ShareActiviy
    if (Intents.Encode.ACTION.equals(action)) {
      encodeContentsFromZXingIntent(intent);}
    // 如果传递的意图来自 HistoryActiviy 
    else if (Intent.ACTION_SEND.equals(action)) {
      encodeContentsFromShareIntent(intent);
    }
  }

QRCodeEncoder 构造函数的参数含义为:

参数 含义
activity 要求创建 QRCodeEncoder 实例 的 Activity 对象
intent activity 传递给 QRCodeEncoder 的意图对象,其中包括要编码的文字内容等
dimension 编码后得到的比特位图尺寸
useVCard 编码内容是否是电子名片格式(对应分享联系人功能)

而后根据传递的 intent 来判断执行怎样的操作, Intents.Encode.ACTION 是来自 ShareActivity 的意图,而 Intent.ACTION_SEND 是来自 HistoryActivity 的意图。这里我们主要分析对来自 ShareActivity 意图的处理。

其基本处理为:
2021SC@SDUSC Zxing开源代码(十三)EncodeActivity 代码分析_第1张图片
也就是说在 EncodeActivity 创建了 QRCodeEncoder 实例对象后, QRCodeEncoder 就根据传递的 intent 获取到了要创建的二维码编码格式 format、编码的具体文字内容 contents、要呈现的编码内容 displayContents,标题 title。
在预先得到了这些信息后,就可以进行具体编码操作了

QRCodeEncoder.encodeAsBitmap

EncodeActivity 创建 QRCodeEncoder 对象后,就调用了 encodeAsBitmap方法

  Bitmap encodeAsBitmap() throws WriterException {
    // 获取要编码的内容
    String contentsToEncode = contents;
    if (contentsToEncode == null) {
      return null;
    }
    Map<EncodeHintType,Object> hints = null;
    // 获取文字内容字符编码格式(默认为UTF-8)
    String encoding = guessAppropriateEncoding(contentsToEncode);
    if (encoding != null) {
      hints = new EnumMap<>(EncodeHintType.class);
      hints.put(EncodeHintType.CHARACTER_SET, encoding);
    }
    BitMatrix result;
    try {
      // 调用 core.jar 中的工厂方法,传入编码内容、目标编码格式、尺寸、当前字符格式,返回一个 BitMatrix 对象
      result = new MultiFormatWriter().encode(contentsToEncode, format, dimension, dimension, hints);
    } catch (IllegalArgumentException iae) {
      // 不支持的编码类型
      return null;
    }
    // BitMatrix 以一个一维数组来表示二维码的二维矩阵,这里需要进行转换,把结果放到一个一维的int数组
    int width = result.getWidth();
    int height = result.getHeight();
    int[] pixels = new int[width * height];
    for (int y = 0; y < height; y++) {
      int offset = y * width;
      for (int x = 0; x < width; x++) {
        pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
      }
    }
    // 创建 Bitmap 对象
    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
    return bitmap;
  }

回到 EncodeActivity 的 onResume 方法,最终创建了一个 ImageView 来将返回的 Bitmap 展现在页面上,完成了整个创建二维码的过程。

将两次分析的内容总结,创建二维码的具体流程如下:
2021SC@SDUSC Zxing开源代码(十三)EncodeActivity 代码分析_第2张图片


总结

通过本次代码分析,理清了从获取编码内容,到返回二维码比特位图的整个二维码创建流程。对比看来,Zxing 安卓端的编码处理过程比扫码过程要简单很多,整体逻辑很清晰。到这里,Zxing 安卓端的两大主要功能都分析完毕了,下次博客将分析一些辅助功能的实现

你可能感兴趣的:(山东大学软件应用与实践,android,java)