# Android

> 从 installDebug 到 AAB——launcher、因权限而延迟启动、清单文件、状态栏和返回键。

Source: https://crossfly.dev/zh/docs/platforms/android — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Android 🤖

## 运行
```bash
gradlew :android:installDebug
```
`AndroidLauncher`（一个 `AndroidApplication`）通过 `getMain(canStart)` 创建 `Main` →
`new Main(canStart, getCommandline())`。

## ⚠️ 因权限而延迟启动
在 Android 上，你通常**不会**立即拉起 UI——而是先请求权限。标准做法：
```java
// 在 launcher 中：canStart = false → UI 尚未启动
initializeForView(getMain(false), config);
// … 用户授予权限后（回调）…
main.startApp(true);   // 现在启动 UI（delayed = true）
```
这样，当第一个界面出现时，相机/GPS/Bluetooth 就已经获得授权了（参见
第 4 章 §4.2）。

## 清单文件和权限
在 `AndroidManifest.xml` 中声明你所使用功能的权限（相机、定位、Bluetooth）——
并在 `startApp(true)` 之前于运行时请求它们。

## 状态栏和密度
- **状态栏**会在布局中被考虑在内（`DeviceConfig.statusbarHeight`）。
- **密度**：`Screen.scale` 反映 DPI；由于你使用 `Relative`/分数，UI 会自动适配。

## 返回键
物理**返回**键会被应用捕获（默认会对顶层窗口执行 `hide()`——参见
[窗口栈](/docs/ui/navigation/the-window-stack)）。

## 打包
原生库 `.so`（含 `crossfly-lib`）按 ABI 打包。签名/AAB 以及上传到 Play
Store：[构建与分发](/docs/platforms/building-and-releasing)。

## 最佳实践
- **在** `startApp(true)` **之前请求权限**（延迟启动）——避免界面残缺。
- 在各种密度/屏幕上测试；依靠 `Relative` 进行适配。

## 常见错误
- 拉起 UI（`canStart=true`）之后才请求权限（第一个界面上功能不可用）。
- 忘记在 `AndroidManifest.xml` 中声明权限（运行时请求会静默失败）。

## 另请参阅
- [构建与分发](/docs/platforms/building-and-releasing)
