标签 Android 下的文章

1. 安装和配置 Linux 环境

本指南使用 Ubuntu 24.10 作为开发环境。可从以下链接下载 ISO 文件:

Ubuntu 24.10 官方镜像

安装方式:使用 VMware 进行安装。

1.1 配置 APT 镜像源

打开 /etc/apt/sources.list.d/ubuntu.sources 文件,并将其中的默认镜像替换为推荐的源地址。

Image

1.2 配置网络代理(使用主机的 Clash 代理)

由于虚拟机默认无法访问 Google 网站,因此需同步主机的网络代理。

步骤如下:

  1. 在主机的 Clash 设置中,启用“允许局域网接入 Clash”。
  2. 记住 Clash 提供的代理端口号。
  3. 在虚拟机中:

    • 进入 设置 > 网络 > 代理,选择 手动 配置。
    • 将 HTTP、HTTPS、SOCKS 代理 修改为主机的 IP 地址(可使用 ip addr 命令获取,前三位相同,第四位设为 1)。Image
    • 端口号填入 Clash 代理端口。
    • 确保网络模式为 NAT。

Image

1.3 安装 VMware Tools

安装 VMware Tools 以增强虚拟机体验,可参考以下教程:

1.4 设置屏幕缩放比例(200%)

推荐调整屏幕缩放以提升可读性
  1. 点击屏幕右上角的状态菜单,选择 “设置”。
  2. 在 “显示” 选项中,找到 “缩放” 设置。
  3. 选择 200% 以优化可视体验。

Image

1.5 更新系统软件包

sudo apt-get update

2. 安装必需工具

所有命令均在用户目录(/home/username)下执行。

2.1 安装 Git

sudo apt-get install git

2.2 安装 Repo 工具

mkdir ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
export PATH=~/bin:$PATH
source ~/.profile

2.3 安装 Bazel

curl -Lo ~/bin/bazel https://github.com/bazelbuild/bazelisk/releases/download/v1.11.0/bazelisk-linux-amd64 && chmod +x ~/bin/bazel

3. 获取 Android 内核版本

启动 AVD 模拟器后,输入以下命令获取内核版本:

adb shell uname -r

示例输出:

6.1.23-android14-4-00257-g7e35917775b8-ab9964412

记住 ab 后面的字符串(如 9964412),然后访问以下链接:

https://ci.android.com/builds/submitted/9964412/kernel_virt_x86_64/latest

在页面中找到类似于 aosp_kernel-common-android14-6.1@9964412 的标题。

4. 拉取并编译 Android 内核

在用户目录(/home/username)下执行以下步骤。

4.1 创建工作目录

mkdir androidkernel
cd androidkernel

4.2 初始化 Repo 并同步代码

repo init -u https://android.googlesource.com/kernel/manifest -b common-android14-6.1-2023-12
repo sync

Image

注意:

android14-6.1-2023-12

需根据实际内核版本调整。

4.3 编译内核

tools/bazel run --config=fast --config=stamp --lto=none //common-modules/virtual-device:virtual_device_x86_64_dist -- --dist_dir=virt

Image

编译完成后,生成的 bzImage 文件位于:

bazel-out/k8-fastbuild/bin/common/kernel_x86_64/bzImage

4.4 传输编译后的 bzImage 到主机

由于 VMware Tools 可能无法直接拖拽文件,可通过网盘或 SCP 传输。

5. 测试编译后的内核

5.1 获取虚拟机列表

emulator -list-avds

5.2 启动虚拟机并加载内核

emulator -avd 设备名 -kernel bzImage 路径

若虚拟机能成功启动,则说明内核编译成功。

6. 植入 KernelSU

当虚拟机成功启动后,回到 VMware 终端,在 androidkernel 目录下执行:

curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -

Image

然后重新执行 Bazel 构建(命令同上),生成带 KernelSU 的内核,并传输到主机。

7. 启动 KernelSU

使用以下命令加载 KernelSU 内核:

emulator -avd 设备名 -kernel 植入后的 bzImage 路径

启动后,下载并安装 KernelSU 管理器:KernelSU Releases

安装后,可继续安装 ZygiskNext、Shamiko、LSposed 等模块。

建议

:VMware 下的 Linux 虚拟机推荐使用

挂起

而非直接关机,以减少重启带来的配置问题。

Image

Image

参考文档

Android 用户是否也想拥有像 iOS 一样在一个页面滑动到完全回退之前就能看到之前的页面的功能呢?

预测性返回(Predictive Back)是 Android 13 引入的手势导航特性。当用户在屏幕边缘执行返回滑动时,当前界面会跟随手势缩小或移动,同时后方界面(或主屏幕)开始显现。用户可以在看到预览后决定是否松开手指完成返回,或反向滑动取消操作。

优势与劣势

优势:
提前预览返回目标,避免因误触边缘而意外退出应用或丢失当前操作状态,可视化的预览让用户明确知道“返回”会去哪里,交互更直观。配合系统动画,跨 Activity、跨任务以及返回主屏幕的过渡更加自然连贯。

劣势:
生态适配不一致是当前最主要的问题。许多第三方应用(如部分版本的 Spotify、Chrome)尚未完全适配,导致部分场景下有预览动画,部分场景下只有传统返回箭头,交互体验割裂。对于不熟悉该特性的用户,同一个返回手势在不同应用中表现不同,可能造成困惑,部分用户因此回流至传统的三键导航。旧版 onBackPressed 和 KEYCODE_BACK 回调在新机制下行为改变,开发者必须迁移至新的 API 才能正确拦截手势。

标准实现代码

最推荐的方式是使用 AndroidX 的向后兼容 API。如果你的项目使用了 Compose,可以直接使用 PredictiveBackHandler;如果是传统 View 体系或需要更底层的控制,则通过 OnBackPressedCallback 配合 OnBackPressedDispatcher。

Jetpack Compose(推荐):
使用 PredictiveBackHandler 可以获取 Flow<BackEventCompat>,实时读取手势进度(progress 值 0~1)来实现自定义动画。

// 确保依赖: androidx.activity:activity-compose:1.8.0+
PredictiveBackHandler(enabled = shouldInterceptBack) { progress: Flow<BackEventCompat> ->
    try {
        progress.collect { backEvent ->
            // 根据 backEvent.progress 更新 UI 动画,例如缩放、位移
            myAnimatable.snapTo(1f - backEvent.progress)
        }
        // 手势完成,执行真正的返回逻辑(如 popBackStack)
        navController.popBackStack()
    } catch (e: CancellationException) {
        // 手势被取消,恢复 UI 状态
        myAnimatable.animateTo(1f)
        throw e
    }
}

传统 View 体系(AndroidX):
核心是使用 OnBackPressedCallback,它会在启用预测性返回的应用中自动获得动画进度回调。

// 1. 依赖: androidx.activity:activity:1.6.0+
// 2. AndroidManifest 中启用(默认通常已启用,可显式声明)
// <application android:enableOnBackInvokedCallback="true" ...>

class MyActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 创建 Callback,仅当需要拦截时才启用
        val callback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                // 执行自定义返回逻辑(如切换 Fragment)
                supportFragmentManager.popBackStack()
            }
            // 如需自定义动画,重写进度相关方法
            // override fun handleOnBackProgressed(backEvent: BackEventCompat) { ... }
            // override fun handleOnBackCancelled() { ... }
        }
        onBackPressedDispatcher.addCallback(this, callback)
    }
}