在前面的博客分析了当在主页面点击“创建二维码”后,所进入的页面 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(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 意图的处理。
其基本处理为:
也就是说在 EncodeActivity 创建了 QRCodeEncoder 实例对象后, QRCodeEncoder 就根据传递的 intent 获取到了要创建的二维码编码格式 format、编码的具体文字内容 contents、要呈现的编码内容 displayContents,标题 title。
在预先得到了这些信息后,就可以进行具体编码操作了
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 展现在页面上,完成了整个创建二维码的过程。
通过本次代码分析,理清了从获取编码内容,到返回二维码比特位图的整个二维码创建流程。对比看来,Zxing 安卓端的编码处理过程比扫码过程要简单很多,整体逻辑很清晰。到这里,Zxing 安卓端的两大主要功能都分析完毕了,下次博客将分析一些辅助功能的实现