让WCDB兼容最新版Room
先直接推荐我的开源小库:WCDBRoomX ,如果它的README就已经让你知道库的核心作用,这篇文章就不需要看了。
WCDB是腾讯微信团队开源的客户端数据库框架,拥有高性能和支持加密等重要特性,并且可用于Android、iOS、Windows、macOS等多个平台。 我们知道,原生的加密数据库框架SQLCipher和不加密的SQLite相比,性能差距还是很大的,加密会使得读写效率严重下降,而WCDB很好地兼顾了性能和安全问题。
SQLCipher和SQLite对比测试
WCDB和SQLite对比测试
对使用了Google官方Jetpack Room库的开发者,WCDB 1.x版本也提供了完美支持:Use WCDB with Room ,然而,WCDB 2.x版本后变成了一个纯ORM框架,虽然也支持Java、Kotlin等语言(本质上就是一层封装,底层接口都一样),但是暂时没有计划支持兼容Room,从官方文档看,2.x版本更纯粹,一套代码跨全平台,所以也不关注各平台的其他框架兼容了。
跟WCDB的开发者也聊了聊,他们团队对Room的支持兴趣不大:issues#1052 。其实 ...
双进程交互实现App自动重启
背景你可能会好奇,有些手游(比如王者荣耀)是怎么实现资源更新后自动重启的?
这个体验确实不错,因为不需要用户手动点击桌面图标重启App,在一些数据恢复备份的场景中,很实用。比如,从云端拉取SQLite数据库db文件或一些prefs配置文件后,会直接覆盖到本地,但进程不重新启动的话,是不会生效的。
思路基本思路其实很简单,利用Android应用对多进程的天然支持,来实现双进程互拉。
有的朋友一看见“双进程”、“互拉”这些词汇就会立马联想到保活,注意本文不是讲保活的哦。
为了方便讲解,我们定义主进程之外的另一个进程为 进程B。大致流程分这么几步:
在主进程执行完一系列业务逻辑后,欲重启,先拉起进程B
进程B启动后,主进程kill掉自己
接着,进程B拉起主进程,然后再kill掉自己,此时主进程完成自动重启
实现先在Manifest中声明进程B,为了良好的交互体验,需要实现一个Activity,进程名称自定义,比如此处叫“killer”,是不是很贴切?
12345<activity android:name=".KillerActivity" an ...
在assembleRelease之前执行自定义任务
背景在实际的Gradle项目开发中,我们总是会遇到一些需求,要在release编译的时候执行一些任务,但debug时不需要。然而,Gradle编译有自己的一套生命周期,比如Android项目的assembleRelease任务在编译启动之前是没有办法静态获取到的。
下面我们就以“去除release版本中的logcat日志打印”为例,做一个简单的梳理。
源码修改模板(module)级别的 build.gradle.kts 文件,我们初步目标是在编译刚启动但还没实际开始执行任务时插入我们的自定义任务,切入点就是Gradle的preBuild任务,这个是预定义的,所以可以进行静态配置:
1234567891011121314151617181920212223242526272829plugins { id("com.android.application") id("kotlin-android") id("kotlin-kapt")}android { namespace = ...
解决macOS执行fastboot找不到设备的问题
背景最近准备给我的备用机Redmi Note 11 5G刷个类原生的三方ROM,MIUI实在是用腻了。搜罗了一番,在XDA上找到了一个基于Pixel Experience开发的ROM:PixelExperience Plus for Redmi Note 11T/11S 5G/11 5G/POCO M4 Pro 5G (everpal),它的实际开源地址是:github.com/Xiaomi-MT6833/releases/releases/,可以直接在里面下载到最新的ROM刷机包和boot.img文件。
下载好PixelExperience_Plus_everpal-13.0-20230410-1707-UNOFFICIAL.zip和boot.img之后,开始刷机,其实过程非常简单(参考:小米手机刷PixelExperience系统操作指南),保证手机已经先解锁BL,并和电脑连接,然后终端执行命令,忽略指南中刷vendor那一步:
123adb reboot-bootloaderfastboot flash boo ...
给不蒜子(busuanzi)统计数据增加初始值
背景最近把个人博客迁移到了Hexo框架,并使用了Butterfly主题,得益于博客框架的易用性和主题功能的丰富程度,感觉非常的香。我对比了很多Hexo主题,这一个算是在功能、审美、文档等各方面几乎完美符合我需求的。
Butterfly很贴心地集成了不蒜子计数工具,可以统计网站的访问数据(人数,次数等)。只需要修改主题config文件即可开启:
1234busuanzi: site_uv: true site_pv: true page_pv: true
即便没有使用Hexo框架和Butterfly主题,用不蒜子计数也是很简单的。
这个工具存在快十年了,其首页的标语就是“两行代码,搞定计数”。感觉这位作者也是个有情怀的开发者,维护服务器给大家免费使用这么多年。
12<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script> <span id="busuanzi_container_si ...
Android系统兼容适配踩坑(持续更新)
屏幕亮度范围在Android应用层,要获取屏幕亮度,一般是通过读取系统Settings表中的配置:
1Settings.System.getInt(contentResolver, Settings.System.SCREEN_BRIGHTNESS);
从AOSP源码可以看出,其范围是0到255,如果要修改亮度,也是通过这个key去putInt的:
1234/*** The screen backlight brightness between 0 and 255.*/public static final String SCREEN_BRIGHTNESS = "screen_brightness";
原则上无论什么设备,厂商都应该按照这个亮度范围去做类似“归一化”的适配,才能让上层开发者写出可靠的代码。
实际上,这个范围值并不可靠,很多厂商根本没在意这个源码注释中的255上限。这就导致了开发者以为修改成255就是最大亮度,但效果不符合预期。
我们可以通过获取最大亮度的配置值来验证:
12int id = getResources().getIdentifier ...
在Android应用中集成使用traceroute工具
背景知识traceroute是一个常用于Linux系统的网络工具,它可显示数据包在IP网络中所经过路由的IP地址,理想状态下可探测本机和目标地址之间的所有路由节点。
其他操作系统中也有类似的替代品,实现都大同小异。一般用法如下:
123456789101112131415161718终端输入:~ traceroute -I baidu.com输出:traceroute to baidu.com (39.156.66.10), 30 hops max, 60 byte packets 1 9.102.191.130 (9.102.191.130) 0.638 ms 0.797 ms * 2 * 9.102.250.222 (9.102.250.222) 0.745 ms 0.943 ms 3 * * * 4 10.200.46.253 (10.200.46.253) 1.332 ms 1.333 ms 1.332 ms 5 * * * 6 39.156.0.85 (39.156.0.85) 4.384 ms 4.184 ms 3.936 ms 7 111 ...
给MIUI开发一个刷新率开关
背景我们很容易发现,现在小米等厂商支持高刷新率120Hz的手机,在系统设置中都隐藏了90Hz这个档位,只有60和120两种选项。对很多人来说,60虽然省电但是太不流畅,影响体验,120虽然流畅但太耗电,出门会有电量焦虑,折中的90其实才是最合适的选择(至少在心理上)。
我一直试图搞清楚为什么厂商不愿意开放90Hz这个选项,对系统来说,刷新率无非就是一个可以修改的数值。是什么原因不让用户多一个选择呢?
调查经过一些简单的查询,我发现网络上的解释一般都是硬件本身不支持,芯片功能较弱,不足以驱动多种刷新率,强制修改为90Hz长时间可能造成屏幕损坏等。
当然,我也不忘去问一问无所不知的ChatGPT,他还是一如既往地说了一些车轱辘话。他这个“技术退步”论倒是有点意思。
其实“硬件不支持”这个说法我并不是很赞同。如果你在Android系统的开发者选项中打开“显示屏幕刷新率”的开关,就会发现在不同的使用场景下,不只有60Hz和120Hz两种刷新率,比如息屏AOD为了降低功耗,就只有30Hz;很多手游最高也只支持90Hz,即便开启120Hz也没用。因此,要是说强制修改为其他隐藏刷新率会导致屏幕损 ...
Android系统无限重启漏洞
2022年,一次偶然的机会,我发现了一个会导致Android系统无限重启致使设备完全不可用的高危漏洞,遂提交给了Google。当年11月的AOSP补丁对此进行了修复,本文是我提交漏洞报告的原文,现公开,待整理。具体可以在Android Security Bulletin—November 2022中搜索CVE-2022-20414了解更多。
Report description
In a few words describe your bug. This will help you search for it later.
The “snoozeNotification” method of NotificationListenerService causes Android system to crash and cyclic reboot.
Bug locationWhich product or website have you found a vulnerability in?Android
The problemPlease describe the technical ...
删除Android Studio中重复的JDK配置
问题可能因为一些不经意的操作,导致如下这种情况:出现多余重复的JDK路径配置,其实指向的是同一个路径。
强迫症犯了之后,就会想怎么干掉这个(2)。
解决第一步:先打开你最近打开的项目,找到 .idea/misc.xml 看看里面有没有那个多余的JDK路径,如果有就直接把这个misc.xml文件删掉。然后完全退出整个Android Studio。
第二步:在Android Studio缓存配置目录里找到 options/jdk.table.xml ,针对不同的系统路径不太一样:
WindowsC:\Users\username\AppData\Roaming\Google\AndroidStudioX.Y
Linux/home/username/.config/Google/AndroidStudioX.Y和/home/username/.local/share/Google/AndroidStudioX.Y
macOS~/Library/Applica ...
当Google关心起你的健康数据
此文为初稿备份,终稿已发布于少数派:https://sspai.com/post/77024
今年五月,在 Android 开发者官方博客中,Google 隆重介绍了一个新平台,名为 Health Connect,并推出了相应的 Android API。其官方网站用非常显眼的大标题和副标题简洁地描述了其核心功能与优势:简化健康类应用之间的连接。
Health Connect: simplify connectivity between apps
Health and fitness apps record valuable data. With permission from your users, you can unlock the full potential of this data by combining it to generate powerful insights.
粗略地看这应该是 Google 搞的一个平台化的东西。那么它具体是什么呢?又会给用户和开发者带来什么利益?
什么是Health Connect如今健康和健身类的应用越来越多,各大厂商迅速占领这个细分 ...
让终端命令更有时间观念
背景我们无论是在Mac还是Linux平台上工作,都避免不了要使用终端来执行命令。然而系统默认的终端功能非常简单,没有命令建议、自动补全等功能,对强依赖终端的工作者来说很不友好。
还好有oh-my-zsh,它对zsh进行了增强,不仅有丰富的插件,还可以自定义主题配置。了解或使用过它的同学一定会觉得非常香。这里引用一篇少数派作者之前的文章,我就不赘述它的好处了:Oh My Zsh 配置指南
使用安装和使用都非常简单,在安装了zsh的前提下,一行命令即可搞定:
123sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"# 或者sh -c "$(wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)"
特别提醒: 如果访问不了GitHub的话,可以使用国内镜像备份仓库:
12git clone https://gitee.com/mirrors/o ...
简单几步实现内网穿透
场景为了避免阐述过多理论,我们直接从需求场景入手,来了解一下为什么需要内网穿透?
小明是少数派的一位咕咕作者,在家里电脑稿某文稿了一半,到公司后打算摸鱼继续稿,怎么办呢(此处假定他没有使用任何云同步软件,也不会使用git,就算会用他也忘了提交)?
此时,小明想通过ssh等远程访问设备文件的方式来下载家里那半稿子,但他的家庭网络是没有分配公网IP的,无法通过互联网直连。内网穿透就这样派上用场了。
所以通俗地讲,内网穿透就是要将流量从公网穿透到内网,让内网设备也能通过公网访问,帮助小明在公司访问家里电脑的文件。
设施内网穿透的核心思想就是“映射”和“转发”,把内网设备的端口映射到公网设备的端口上,来进行流量转发。
简单地画一下示意图如上,基础设施由两个核心设备组成:
服务端:拥有公网IP的设备一台,即上图“公网服务器”,开放2个端口7000和6000,用于公网通信。
客户端:要访问的内网设备一台,即上图”内网家用电脑”,开放实际应用服务所需的端口(比如ssh服务,默认22端口),并将配置的公网映射端口6000告知服务端。所以服务端开放的那个端口6000实际上是客户端告诉它的。
(以上 ...
谁家推送服务限制最严格
先说句题外话,又过了这么多年了,没想到国内Android的统一推送还是没有实现。
由于工作需要,最近正好在调研各家系统推送服务,我发现从他们的技术文档可以分析出很多有意思的东西,比如说能看出来哪家厂商的推送限制最严格,最考虑用户的综合体验。在讲解之前,我们先简单提几个推送服务的基本概念:
设备:用户所持有的某台设备,在技术文档中所提到的日活跃用户数一般也就指日联网设备数
应用:某台设备上安装的某个应用,后续我们所描述的推送数量限制都是以此维度比较的
推送:应用进程活跃或关闭时,通过系统级的推送通道下发消息,一般以通知消息的形式呈现给用户,点击后激活应用进程
透传:仅在应用活跃时可接收数据,仍然依赖系统的推送服务器下发,但数据格式一般可以自定义,处理逻辑也是由应用自己实现,所以应用如果被杀死,自然就处理不到了
一个不那么规范的示意图:
注:下文以x表示日联网设备数量;我们主要关注推送,不过多说明透传的限制。
各家次数限制华为对于某设备某应用,推送和透传次数总共不超过3000次/每日;相当于该应用每日推送总量上限为:f(x) = 3000 * x
简要解读:华为严格限 ...
解决iptables导致无法联网的问题
问题先说下我的单机环境是Ubuntu 16.04,只放了点小应用,一直没升级系统(懒),防火墙规则也是简单地使用iptables来控制。
今天我因需要重启服务器之后,发现突然连不上了,ssh无法连接,ping也不通,我开始慌了。于是我只能进入云服务器商的后台,用网页版登录,不管你是阿里云还是腾讯云还是国外的服务商,现在大多都有这种功能。
进去之后,先任意ping一个公网IP,提示 “Network is unreachable” ,看来这互联网是彻底断了。用ifconfig也能发现本机的公网IP看不见了。
怎么重启一下就这样了呢?
排查直接检查networking服务状态:
1systemctl status networking.service
能发现服务运行状态不是Active的,并且提示了是由于iptables规则应用失败,其中可以看见 **“cannot resolve host” **之类的字样,具体现场我没有截图保存,大概是这些内容。
原因基本上就清楚了,因为我前段时间手动禁用了某些IP来做测试:
1iptables -I INPUT -s xxx.xxx.xxx.xxx ...