2025-01-30 21:42:51
默认编译出来的 React Native 的 Android APK 包体积巨大,有 70M 这么大。而我平时用原生开发的 Android App,即便加入了 N 多大图片,也才 20M 大小。
感觉还是有必要优化一下的,毕竟打包出来这么大体积的 APK,放出来给人下载,一是浪费存储空间,二是看起来也不专业,容易让人产生疑问,是不是塞了不必要的东西在 App 里面。
Android Studio 内置了一个分析工具,在菜单 build - analyze APK。来看一下,默认编译出来的 APK 分析结果:
可以看到占用最多的是 lib 这个目录,里面有四个文件夹:
大小都差不多,都是 16M 左右。每个目录代表一种 CPU 架构的库文件集合。
By default, the generated APK has the native code for both x86, x86_64, ARMv7a and ARM64-v8a CPU architectures. This makes it easier to share APKs that run on almost all Android devices. However, this has the downside that there will be some unused native code on any device, leading to unnecessarily bigger APKs.
参考:
https://reactnative.dev/docs/signed-apk-android#publishing-to-other-stores
会看到 GitHub 上好多项目的 release 版本中,也是区分了不同 CPU 架构的 APK 包。 这个可以大大减小安装的 APK 包体积。
比较大的文件都给 react native 有关。
在 app build.gradle 配置文件中,在 defaultConfig 的平级加入:
splits {
abi {
reset()
enable true
universalApk false
//include "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
include "arm64-v8a"
}
}
这里配置取消了 universalApk 的生成,即不再生成一个包含4种 CPU 架构的包。而是不同架构产生不同的 APK 文件。
例如,目前配置对应的 APK 文件名:app-arm64-v8a-release.apk
来看看优化后的包体积大小:
从 70M 降低到了 26M。我安装到了我的红米 K80 Android 机上,没有任何问题。
Most devices today are arm64-v8a, the really cheap devices are armeabi-v7a to save cost, and almost none are x86 or x86_64.
arm64 v8 是 arm 目前的主流架构,上一代架构是 armv7。arm v7没有64位模式,只有32位。而 x86 和 x86_64 几乎没有了,通常只用在 windows 上的模拟器上。
参考:
https://stackoverflow.com/questions/56824557/what-is-the-difference-between-armeabi-v7a-arm64-v8a-x86
2025-01-30 21:35:02
假期写了好几天 react native,发现越发的熟练,于是顺手开发了一个 Android 版本的 博客 app,这样就能随时在手机上写笔记了。
一共实现了三个功能界面,登录界面,列表展示页面,编辑页。
但是功能还不完善,需要像 twitter 一样,加上话题功能,及图片功能。
不过,开发速度已经超出了我的预期,在 GitHub copilot 的辅助下,大概半天就开发上线了。而且在此期间,copilot 的进步肉眼可见,例如 chat 功能在初一的更新后已经可以实时基于文件内容更新了。期间也尝试了一下这两天非常火的 deepseek,估计是用户量暴增,我用了几次要么反应慢,要么提示超时。总体上 GitHub copilot 还是靠谱。👍
开发这个笔记 app 的原因是,小米手机的内置笔记功能不能在 Windows 上使用,那个网页版本不太方便,而且标签功能也不实用。只好自己去实现了。
react native 开发的 app,整体上体验非常流畅。只有冷启动那一下,那个开屏过渡图标页面比较尬,增加一个 slogan 展示作为过渡页也不错 😌 录个视频展示一下(๑˃̵ᴗ˂̵)
2025-01-21 12:08:45
从昨天晚上开始,发现无法直接拉取 github 上的代码仓库了。报错如下:
ssh: connect to host github.com port 22: Resource temporarily unavailable
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
我以为我的 github 账号权限出了问题。
但是换成 https 协议,会报:
Failed to connect to github.com port 443: Connection refused
说明还是网络问题。
> nslookup github.com
Server: 114.114.114.114
Address: 114.114.114.114#53
Non-authoritative answer:
Name: github.com
Address: 20.205.243.166
参考:
https://www.v2ex.com/t/1009169
GitHub 在国内会被解析到新加坡节点的 20.205.243.166 ,这个 IP 在全国范围内被空路由了,其他 GitHub 的 IP 暂时没事,也可能只是策略还没分发完毕
打开配置文件 ~/.ssh/config 添加:
# add
Host github.com
Hostname ssh.github.com
Port 443
然后,就能正常的拉取 github 代码了。
在国内写代码太痛苦了,搞得跟个小偷一样 🤣
2025-01-17 16:33:25
用 Nginx 部署了一个前端项目,发现 pdf.js 相关的功能异常。 从浏览器的 console 来看,报错信息如下:
Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "application/octet-stream". Strict MIME type checking is enforced for module scripts per HTML spec.
参考:
https://github.com/mozilla/pdf.js/issues/17296
在前端配置中增加 mjs 相关的配置即可。
server {
# ...
location / {
root /usr/share/nginx/html;
index index.html;
location ~* \.mjs$ {
# target only *.mjs files
# now we can safely override types since we are only
# targeting a single file extension.
types {
text/javascript mjs;
}
}
}
}
mjs 即,MJS(ECMAScript Modules in JavaScript)使用 .mjs 作为文件扩展名,以明确表示该文件使用 ECMAScript 模块系统。
2025-01-16 10:01:50
之前开发 app 都是基于手机系统 locale 实现多语言翻译就行。
但是在 AI 横行的时代,又多了一项需求,就是根据手机系统的语言,自动返回对应语言的聊天内容。
这样就需要传递一个语言参数给后台接口。
An IETF BCP 47 language tag without the region code. Example: 'en', 'es', 'pl'.
而 locale 则是 languageCode 和 regionCode 的组合。例如 en-US, zh-CN. 当然还有其他的 code 组合。
在 React Native 项目下执行:
npx expo install expo-localization
这个库同时支持 android, ios 和 web。
import { getLocales } from 'expo-localization';
const language = getLocales()[0].languageCode; // en / es
getLocales 返回的数据格式:
[{
"languageTag": "pl-PL",
"languageCode": "pl",
"textDirection": "ltr",
"digitGroupingSeparator": " ",
"decimalSeparator": ",",
"measurementSystem": "metric",
"currencyCode": "PLN",
"currencySymbol": "zł",
"regionCode": "PL",
"temperatureUnit": "celsius"
}]
https://docs.expo.dev/versions/latest/sdk/localization/
2025-01-12 11:32:21
https://www.npmjs.com/package/react-native-vimeo-iframe
但是直接使用 Vimeo 组件,会报错:
Video is not implemented by GiftedChat. You need to provide your own implementation by using renderMessageVideo prop.
于是增加了 gifted chat 的自定义方法:
renderMessageVideo
增加了 renderMessageVideo 还是报错:
React Native WebView does not support this platform.
npm install react-native-webview
react-native-webview 仅支持移动平台,不支持 Web 平台。对于 Web 平台,可以使用 iframe 来嵌入 Vimeo 视频。
所以区分 Platform 做不同处理:
const renderMessageVideo = (props: any) => {
const { currentMessage } = props
if (currentMessage.video) {
if (Platform.OS === 'web') {
return (
<div>
<div>
<iframe
title="Some Video"
src="https://player.vimeo.com/video/xxx"
frameborder="0"
width="300"
height="361"
allow="autoplay; fullscreen; picture-in-picture"
allowfullscreen
></iframe>
</div>
<script src="https://player.vimeo.com/api/player.js"></script>
</div>
);
} else {
return (
<Vimeo
videoId={'xxx'}
params={'api=1&autoplay=0'}
/>
)
}
}
return null
}
return (
<GiftedChat
messages={messages}
onSend={msgs => onSend(msgs)}
user={user}
onQuickReply={handleQuickReply}
renderMessageText={renderMessageText}
renderMessageVideo={renderMessageVideo}
renderTime={renderTime}
/>
)