在电梯和高铁上有些时候网络不好,这时候刷行動裝置加载不出来就很难受。
很多时候刷手机都是访问一些网站,而很多网站都是全部由静态文件构成的。然而当你点击进主页的时候没有一次性将所有资源到下到行動裝置上,导致后续点击站内的链接需要等待加载。
有没有可能将所有资源全都下载下来供浏览器浏览呢呢?
一种方式是将所有 html,css,js 文件下载到手机,然后启动一个 darkhttpd 这样的 web server,再用浏览器导航到 localhost:8080 访问,不过这样有点繁琐。
一个跨平台程序框架 Tauri v2 提供了更容易的方式,方法如下:
使用 vanilla 模板新建工程
pnpm create tauri-app -m pnpm -t vanilla --identifier app.xjtu.rust-doc xjtu-tauri-app-rust-doc
cd xjtu-tauri-app-rust-doc
pnpm install
pnpm tauri android init
然后把包含 index.html 的静态资源目录全部放到 src
目录底下:
rsync -av --delete ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/doc/rust/html/ ./src/
参照 Android Code Signing | Tauri 修改以下文件,添加 release 编译所需的凭据信息:
src-tauri/gen/android/keystore.properties
password=7
keyAlias=xj
storeFile=/app.jks
src-tauri/gen/android/app/build.gradle.kts
import java.util.Properties
import java.io.FileInputStream
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("rust")
}
val tauriProperties = Properties().apply {
val propFile = file("tauri.properties")
if (propFile.exists()) {
propFile.inputStream().use { load(it) }
}
}
android {
compileSdk = 34
namespace = "app.xjtu.static_app"
defaultConfig {
manifestPlaceholders["usesCleartextTraffic"] = "false"
applicationId = "app.xjtu.static_app"
minSdk = 24
targetSdk = 34
versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0")
}
signingConfigs {
create("release") {
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = Properties()
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["password"] as String
storeFile = file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["password"] as String
}
}
buildTypes {
getByName("debug") {
manifestPlaceholders["usesCleartextTraffic"] = "true"
isDebuggable = true
isJniDebuggable = true
isMinifyEnabled = false
packaging { jniLibs.keepDebugSymbols.add("*/arm64-v8a/*.so")
jniLibs.keepDebugSymbols.add("*/armeabi-v7a/*.so")
jniLibs.keepDebugSymbols.add("*/x86/*.so")
jniLibs.keepDebugSymbols.add("*/x86_64/*.so")
}
}
getByName("release") {
isMinifyEnabled = true
signingConfig = signingConfigs.getByName("release")
proguardFiles(
*fileTree(".") { include("**/*.pro") }
.plus(getDefaultProguardFile("proguard-android-optimize.txt"))
.toList().toTypedArray()
)
}
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
buildConfig = true
}
}
rust {
rootDirRel = "../../../"
}
dependencies {
implementation("androidx.webkit:webkit:1.6.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.8.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.4")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.0")
}
apply(from = "tauri.build.gradle.kts")
构建 APK:
tauri android build --apk --target aarch64
效果展示:
-
Rails Guides with old UI:
https://assets.xjtu.app/pool/app.xjtu.rails-guides.apk -
Rust Doc (
rustup doc --book
)
https://assets.xjtu.app/pool/app.xjtu.rust-doc.apk
Hidden
Play Store 上面有别人不知道用什么高级方法打包的 APK:
https://play.google.com/store/apps/details?id=com.rust_doc.md_ismail_hosen
https://play.google.com/store/apps/details?id=com.rust_book.example