Tauri2.0移动端开发遇到的问题和解决

1,011 阅读3分钟

前言

下面会持续记录一些问题和解决方案,以便未来之用。

1. 安卓只想打包特定的abi

打开文件 src-tauri/gen/android/buildSrc/src/main/java/com/example/app/kotlin/RustPlugin.kt 进行修改,切记删除 (findProperty("自定义属性") as? String)?.split(',') ?: 这一类的代码。

  • 修改前
// 前面的代码保持不变

val defaultAbiList = listOf("arm64-v8a", "armeabi-v7a", "x86", "x86_64");
val abiList = (findProperty("abiList") as? String)?.split(',') ?: defaultAbiList

val defaultArchList = listOf("arm64", "arm", "x86", "x86_64");
val archList = (findProperty("archList") as? String)?.split(',') ?: defaultArchList

val targetsList = (findProperty("targetList") as? String)?.split(',') ?: listOf("aarch64", "armv7", "i686", "x86_64")

// 后面的代码保持不变
  • 修改后
... // 前面的代码保持不变

val defaultAbiList = listOf("arm64-v8a");
val abiList = defaultAbiList

val defaultArchList = listOf("arm64");
val archList = defaultArchList

val targetsList = listOf("aarch64")

... // 后面的代码保持不变

2. 如何给安卓签名

方法一

打开文件 src-tauri/gen/android/app/build.gradle.kts,添加下面的代码:

android {
    
    // 其他代码不变
    
    signingConfigs {
        create("release") {
            keyAlias = tauriProperties.getProperty("keyAlias")
            keyPassword = tauriProperties.getProperty("keyPassword")
            storeFile = file(tauriProperties.getProperty("storeFile"))
            storePassword = tauriProperties.getProperty("storePassword")
        }
    }
    
    // 其他代码不变
}

打开文件 src-tauri/gen/android/app/tauri.properties,添加下面的属性:

keyAlias=yourKeyAlias
keyPassword=yourKeyPassword
storeFile=keystore.jks
storePassword=yourStorePassword

方法二

还有一种是从环境变量读取,推荐这种,在文件 src-tauri/gen/android/app/build.gradle.kts 添加下面的代码:

import java.io.File
import java.util.*

android {
    
    // 其他代码不变
    
    signingConfigs {

        create("release") {

            if (project.gradle.startParameter.taskNames.any { it.contains("Release") }) {
                val keystoreBase64 = System.getenv("KEYSTORE_BASE64")

                if (keystoreBase64 != null) {
                
                    val keystoreFile = createTempFile(suffix = ".jks").apply {
                        deleteOnExit()
                        writeBytes(Base64.getDecoder().decode(keystoreBase64))
                    }

                    keyAlias = System.getenv("KEYSTORE_KEY_ALIAS") ?: error("Missing KEYSTORE_KEY_ALIAS")
                    keyPassword = System.getenv("KEYSTORE_KEY_PASSWORD") ?: error("Missing KEYSTORE_KEY_PASSWORD")
                    storeFile = keystoreFile
                    storePassword = System.getenv("KEYSTORE_PASSWORD") ?: error("Missing KEYSTORE_PASSWORD")
                }
            }

        }
    }
    
    // 其他代码不变
}
  • 下面是环境变量
KEYSTORE_KEY_ALIAS=yourKeyAlias
KEYSTORE_KEY_PASSWORD=yourKeyPassword
KEYSTORE_BASE64=yourKeyFileBase64
KEYSTORE_PASSWORD=yourkeyFilePassword

keystore.jks 文件需要转成Base64存储。

如果觉得麻烦,使用提供的脚步快速生成,脚本代码在 scripts/gen_android_key.sh,会在根目录创建一个 .env.local 的文件

3. 为什么 pnpm tauri android build 打出的是未签名的包,如:app-universal-release-unsigned.apk

在文件 src-tauri/gen/android/app/build.gradle.kts 修改如下:

android {
    // 其他代码不变
    
    buildTypes {
    
        // 其他代码不变
        
        getByName("release") {
        
            // 添加这一行
            signingConfig = signingConfigs.getByName("release")
            
            // 其他代码不变
        }
    }
    
    // 其他代码不变
}

4. 安卓构建失败,报错误:Process 'command 'xxx'' finished with non-zero exit value 1

打开文件 src-tauri/gen/android/buildSrc/src/main/java/com/example/app/kotlin/BuildTask.ktval executable = """xxx"""; 中的xxx改成自己的包管理工具。

我的包管理工具是 pnpm,所以改成:

val executable = """pnpm""";

5. 安卓设置安全区域

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
  • 设置安全距离
body {
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
  height: 100vh;
}

6. 安卓输入框在软键盘出现后无法顶起

  • 参考

  • 打开文件 src-tauri/gen/android/app/src/main/AndroidManifest.xml,添加内容:

android:windowSoftInputMode="adjustResize|stateVisible"

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 其他代码不变 -->

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.app"
        android:usesCleartextTraffic="${usesCleartextTraffic}">
        <activity
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
            android:launchMode="singleTask"
            android:label="@string/main_activity_title"
            android:name=".MainActivity"
            android:windowSoftInputMode="adjustResize|stateVisible" 
            android:exported="true">
            <!-- 其他代码不变 -->
        </activity>

        <!-- 其他代码不变 -->
    </application>
</manifest>

7. 沉浸式状态栏

  • 参考

  • 打开文件 src-tauri/gen/android/app/src/main/res/values/themes.xml,添加内容:

<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="Theme.app" parent="Theme.MaterialComponents.DayNight.NoActionBar">
      <item name="android:statusBarColor">@android:color/white</item>
      <item name="android:windowLightStatusBar">true</item>
    </style>
</resources>
  • 打开文件 src-tauri/gen/android/app/src/main/res/values-night/themes.xml,添加内容:
<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="Theme.app" parent="Theme.MaterialComponents.DayNight.NoActionBar">
      <item name="android:statusBarColor">@android:color/black</item>
      <item name="android:windowLightStatusBar">false</item>
    </style>
</resources>