可爱的程序猿 - CoderYuan.com

改变世界的猿类——袁国正的个人网站

什么是 KMM?

KMM 全称:Kotlin Multiplatform Mobile,是基于 Kotlin 语言进行多平台开发的一套技术框架,它和 Kotlin Native(简称 KN)有一定联系,但 KMM 主要面相移动端开发,即:Android、iOS、Web,而 KN 则主要面相 Linux、macOS、Windows 等

当然,KMM 在 iOS 平台的实现,离不开 Kotlin Native,Kotlin 代码最终会在 iOS 工程中生成一套 Framework 库,可供 Objective-C、Swift 进行调用

KMM 宗旨是使用 Kotlin 语言和技术栈,开发一套可以在多平台之间共享的代码库,用来构建统一的代码逻辑,而不用针对各个平台都去实现自己的一套,从而导致人力的浪费

这里引用 Kotlin 官网的一张图来说明 Kotlin 多平台的工作原理

Kotlin 多平台
阅读全文 »

先讲讲怎么回事

不知道怎么的,大概是从 19 年双十一前,我在家里刷淘宝(天猫、闲鱼等)的时候,图片经常加载的特别慢,家里是北京电信的 100M 宽带,另外还有一张电信的手机卡,无论宽带还是 4G,图片都刷的很慢,网速正常,SpeedTest 测试速度都是正常的,其他 App 也都 OK

taobao-image

部分家里使用电信宽带的同事也遇到了类似的问题,但都以为是家里网速的问题,所以也没有向淘宝进行反馈,只是在需要的时候,切成 4G 使用罢了

今年 5 月宽带到期,由于淘宝的问题,差点就换了联通的,但由于联通略贵(500M,166/月),电信(200M,600+/年),而且疫情期间,懒得折腾了,直接续费吧

于是就想着怎么解决一下淘宝图片的问题

阅读全文 »

1 介绍

本规范参考Android 官方 Kotlin 编码规范,旨在为 Kotlin 开发人员提供编码风格上的指导,仅供参考,如果翻译上的失误或建议,欢迎反馈!

2 源文件规范

2.1 文件编码

  • 所有源文件必须使用 UTF-8 进行编码

2.2 文件命名

  • 所有源文件必须使用.kt作为扩展名

  • 如一个源码文件仅包含一个顶级类,则该文件应当以这个定级类的类名作为文件名,如包含多个顶级定义,请选择一个能够描述该文件内容的名字作为文件名

2.3 特殊字符

2.3.1 空格

  • 除了换行符之外,ASCII 空格(0x20)是唯一合法的空格字符

    • 所有在源代码中(包括字符、字符串以及注释中)出现的其他空格字符都需要转义
    • Tab 不可以用于缩进

2.3.2 特殊转义字符

  • 任何含有特殊意义的转义字符,如:\b\n\r\t\'\''\\\$等,不可以使用 Unicode 进行转义
阅读全文 »

为什么 HTTPS 不能抓包了?

Google 在 Android 7.0 以后的版本中,添加了“网络安全配置(Network security configuration)”的相关配置项。其旨在增强 App 的安全性,可以避免 TargetSDK 版本>=N 的 App 内部网络请求在非测试环境下被恶意抓包。

Network Sercurity Configuration 对安全性的保证,主要是通过以下几个途径:是否允许明文 HTTP 请求(非 HTTPS)、HTTPS 证书(区分系统、用户)信任设置、域名以及 App 的 Debug 或 Release 配置,只有符合 Manifest 中配置的 NetworkConfig 字段内容下的条件,才可以进行正常的 HTTP 请求,如果需要使用 Charles、Fiddler 等工具进行抓包,也需要利用 NetworkConfig 来配置可以信任的证书,否则 HTTPS 请求在 CONNECT 阶段,就会返回错误,同时 LogCat 会打印出类似以下的错误信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Caused by: java.security.cert.CertificateException: xxx.
at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:661)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:539)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:605)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:495)
at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:321)
at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:113)
at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:87)
at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:116)
at com.huawei.secure.android.common.ssl.SecureX509TrustManager.checkServerTrusted(:105)
at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:212)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket.verifyCertificateChain(ConscryptFileDescriptorSocket.java:404)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:375)

通常,Android 开发者会将 NetworkConfig 按照以下 XML 文件进行配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<!-- 允许明文 HTTP(非 HTTPS)请求 -->
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<!-- 其他情况只允许信任系统内置证书 -->
<certificates src="system"/>
</trust-anchors>
</base-config>
<!-- 仅 Debug 包允许用户证书 -->
<debug-overrides>
<trust-anchors>
<certificates src="user"/>
</trust-anchors>
</debug-overrides>
</network-security-config>

然而对于开发者来说,通常 App 发版上线会选择使用 Release 版本的安装包,如果希望对 Release 包抓包,只能使用 Android 6.0 及以下的手机,这样一来,有时候出现线上问题,便无法进行 HTTPS 抓包,并不利于测试和修正

阅读全文 »

由来

一个月前,剁手了 AMD Ryzen Threadripper 2990WX(官网),这个处理器的参数着实牛逼,32 核心 64 线程,总共 80MB 的缓存,可以说秒杀目前所有的桌面级处理器了!狠了狠心,搞了一台,辅以 32GB DDR4 3200MHz 内存和 970 EVO NVMe SSD,经过一番折腾(无 CPU 刷 BIOS、装 Windows/Linux 系统),最终确定使用 Windows 10 专业工作站版作为日常开发使用。

Cinebench R15 跑分:

R15 跑分

CPU-Z 跑分:

CPU-Z

虽然分数不像网上那些人跑得那么高,但也是相当猛了,再加上任务管理器 64 个框框,心里十分舒坦!

阅读全文 »

背景

之前在开发实验室官网(https://www.xiyoumobile.com)的时候,由于图片特别多,学校服务器走电信和教育网,带宽也不够,在某些网络环境图片加载十分缓慢,而且有时候主页打开需要 10s+的时间,所以考虑从图片压缩上节省网络带宽

目前业界的图片压缩方案有以下几种,他们的压缩比都很高,都可以有效减小图片文件的体积

方案 提出者 编码类型 开源 官网 浏览器支持情况
WebP Google VP8 https://developers.google.com/speed/webp/ Chrome、Opera、Edge、Android,及其他基于 Chromium 内核的浏览器
BPG Fabrice Bellard HEVC http://bellard.org/bpg
TPG 腾讯 AVS2(类似 AVC) 未知 QQ 浏览器
JPEG XR 微软 未知 (微软已投奔 WebP) IE、Edge

根据 TPG 推出时腾讯的微信公众号文章来看,TPG 的压缩算法相比 WebP 而言,能够使体积变得更小,图片更清晰,但是适用范围还是太局限了,所以还是选择了 WebP

但主要问题是前端代码中已经固定了某些静态图片资源的 URL 及扩展名,数据库中保存的 HTML 中的图片引用也是如此,即使把图片全部转换为 WebP 格式,如何保证不改动 HTML 及 CSS 代码,就能够对支持的浏览器返回 WebP 格式图片,而不支持的浏览器返回 JPG/PNG?

于是经过一段时间摸索和整理,就有了现在用在我个人网站的 coderyuan-image-server:https://github.com/yuanguozheng/coderyuan-image-server

基本原理及流程

判断浏览器是否支持 WebP

首先引用一段来自 w3 的定义(RFC 2616):https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

The Accept request-header field can be used to specify certain media types which are acceptable for the response. Accept headers can be used to indicate that the request is specifically limited to a small set of desired types, as in the case of a request for an in-line image.

   Accept         = "Accept" ":"
                    #( media-range [ accept-params ] )
   media-range    = ( "*/*"
                    | ( type "/" "*" )
                    | ( type "/" subtype )
                    ) *( ";" parameter )
   accept-params  = ";" "q" "=" qvalue *( accept-extension )
   accept-extension = ";" token [ "=" ( token | quoted-string ) ]

这里定义了 HTTP 请求头中 Accept 字段的含义——表示 Response 可以接受的媒体类型(MIME-Type)

如果支持 WebP,那么 Accept 中将会包含image/webp这样的字符串

于是乎,我们就可以根据浏览器请求图片资源时的 Accept 字段来区分是否真正支持 WebP 格式

为什么不使用 User-Agent?

阅读全文 »

Flutter 是什么

我觉得可以理解为 Google 做的 React Native/Weex,目标也是使用一套代码,同时运行在 Android 和 iOS 上,提供 Native 的性能和体验,也都支持热更新,只不过 Flutter 使用 Dart 语言,React Native 使用 JavaScript,据说 Flutter 的性能要比 RN 好一些,因为没有使用 JSBridge 这样的结构,直接使用 Dart 来操作 Native 控件,具体可以参考它的官网:https://flutter.io/

Flutter 官方文档

上图,Flutter 官方文档的结构,和 React Native 都很像!

最近 Flutter 不知道怎么就火了,之前有人给我提过,现在准备一探究竟

环境搭建

类似 React Native,Flutter 也是同样的套路,需要先下载它的命令行工具,由于需要兼容 iOS,所以还是推荐使用 macOS 来进行开发

由于网络问题,需要设置两个环境变量

1
2
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

然后在 Flutter 的官方 Github clone 它的命令行工具,git clone -b dev https://github.com/flutter/flutter.git,这里建议使用 dev 分支,能及时更新到一些新功能,同时也比 master 分支要稍稳定一些

阅读全文 »

最近在读《Java 并发编程实战》这本书,感觉写的很详细,易懂,可以比较全面地了解 Java 并发编程相关内容,为了以后方便查找,专门做个读书笔记,这篇只总结这本书的第一部分——基础知识

Java 并发编程实战

线程

  • 线程会共享进程范围内的资源(例如:内存句柄和文件句柄),但每个线程都有各自的程序计数器、栈、局部变量

  • 线程也被称为轻量级进程,很多操作系统都以线程为基本的调度单位

  • 同一个进程中的所有线程,共享进程的内存地址空间,可以访问相同的变量,在同一个堆上分配对象(所以多个线程同时访问时,必须使用同步机制来协同访问)

  • 线程的优势:发挥多处理器的能力、建模简单、简化异步事件处理、GUI 响应灵敏

  • 线程带来的风险:安全性、活跃性、性能

  • 安全性:存在竞态条件(同时访问,某个方法不一定返回的是唯一值),使用同步来解决

  • 活跃性:死锁、饥饿、活锁

  • 性能:线程调度器临时挂起活跃线程,并转而运行另一个线程,造成上下文(Context)频繁切换

阅读全文 »

为什么要检测?

Google 在 2018 年的 I/O 大会上发布了 Android P 的 Developer Preview 2(简称 DP2)版本,其中还说明了在以后的 Android P 上,将对非 SDK API 的调用进行限制。目前,开发者对于非 SDK API 的调用,只能采取反射或 JNI 间接调用的方法进行调用。由于 Android 是开源的,所以开发者对非公有 SDK 的调用十分混乱,Google 此举也是为了进一步防止碎片化,规范开发者的 API 使用行为。

Android P 引入非 SDK API 检测

而在运行 Android P 的手机上,启动 APP 时,ART 虚拟机就会对 APP 的 Dex 文件进行检测,比对内置的黑名单、暗灰名单、亮灰名单,一旦发现 APP 内含有上面名的中的调用,就会发出警告,严重的,会直接抛出异常,如果没有进行处理,将导致 APP 的 Crash,即使进行了 try-catch,这些反射调用的功能,也会使用不正常。

阅读全文 »

Smali 是什么?

简介

Smali 是用于 Dalvik(Android 虚拟机)的反汇编程序实现,汇编工具(将 Smali 代码汇编为 dex 文件)为 smali.jar,与之对应的 baksmali.jar 则是反汇编程序(下载地址),官方所说的基于 Jasmin/dedexer 语法,实际根不知道是什么鬼……

Smali 支持注解、调试信息、行数信息等基本 Java 的基本特性,可以说是很接近 Java 编译在 JVM 上的中间语言了,一般用来做 Android 程序的逆向工程,还可以。。搞搞小名堂

个人认为 Smali 只是用于做反汇编的一种语言实现,如果可以,自己也能定义一套这样的语言,实现反汇编的效果

Smali 基础

下面的内容涉及一些 Smali 编程的结构和基本语法,这些基本语法,在使用 Smali 修改 App 逻辑时需要用到

阅读全文 »
0%