将小米平板2从低版本安卓适配到高版本的若干收获与思考

本文记录了作者尝试将小米平板2从Android 6.0适配到7.0的过程中遇到的问题及解决方法,包括下载源码、获取日志、处理dlopen failed错误的技巧,以及目前适配工作中面临的困难和一些体会。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有个愿望:让小米平板2用上64位 Android9.0。因为64位 Android9.0 的 houdini 兼容性非常好,我曾经试过把 houdini9 植入 Android_x86-9.0 r2,然后安装到小米平板2中,发现APP运行很稳定,其它小米平板2安卓系统常见的APP闪退问题基本上都没有。只是因为显卡原因,Android_x86-9.0 r2 在小米平板2上只能运行在 nomodeset 模式下,视频靠CPU解码,导致系统卡顿很厉害。

目标很美好,但对于安卓适配新兵来说,实现这个目标还是要循序渐进。

我手头有能成功编译的 lineage13.0 for latte(小米平板2的代号是 latte)源码,lineage13.0 属于安卓6,为了缩小跨度,降低难度,我决定先从 lineage14.1 的小米平板2适配入手,因为 lineage14.1 属于安卓7,相比安卓6的变化比9要小一些。

虽然适配工作还没有完成,但过程中也有不少收获,总结一下。

一、下载源码

lineage14.1 的主源码可以按 LineageOS Wiki 上的说明下载,latte 的 vendor、device、kernel 则来自 Github( LineageOS Resources for Xiaomi Mi Pad 2 ),但配置 local_mainifest.xml 时要注意:不要使用 cm-14.1 分支的 vendor、device、kernel,它的BUG太多,基于它进行适配工作量巨大,并且会出现很多看不懂的问题。建议用 cm-13.0 分支,因为它已经在 lineage13.0 for latte上适配成功,本身不存在问题,所需要做的是对 lineage14.1 调试。

二、获取日志

最初编译出来的 lineage14.1 Rom 安装到小米平板2上多半无法成功运行,需要查看日志来分析原因,但系统如果没有运行到合适的阶段是无法通过 ADB 获取日志的,怎么办?群友 ygjsz 提供了一个方法。

在 init.rc 中加入以下代码:

# Take logs even when adb is not working.
# Thanks: markakash
# Add these lines to your init.rc file:
    
service boot_lc_main /system/bin/logcat -f /cache/boot_lc_main.txt
    class main
    user root
    group root system
    oneshot

service boot_dmesg /system/bin/sh -c "dmesg > /cache/boot_dmesg.txt"
    class main
    user root
    group root system
    oneshot

on property:sys.boot_completed=1
    start boot_lc_main
    start boot_dmesg

这段代码在开机后会自动把日志记录到 cache 文件夹中。当系统启动失败后,长按电源键+音量增键,让平板进入 Recovery 模式,就能把日志拷贝出来分析。

三、处理 dlopen failed 错误

日志中常出现 dlopen failed 报错,形式为 cannot locate symbol "_ZNxxxx" referenced by "xxxxx.so",例如:

 dlopen failed: cannot locate symbol "_ZN7android13GraphicBufferC1Ejjij"  referenced by "/system/vendor/lib/hw/hwcomposer.gmin.so"

这里需要重点搞清 symbol "_ZN7androidxxxxxx" 是什么?简单说,它是系统在编译 so 时自动生成的某个函数的别名,这个函数在源码中本来有易理解的名称,但在编译时编译器给它生成了一个 symbol,这个 symbol 具有唯一性,生成规则与函数名称、参数个数和参数类型有关,系统运行时根据它就可以定位到具体的动态库中具体的函数。

解决这个报错的第一步是要定位这个函数,但由于不知道生成规则,所以无法直接解码 symbol 去定位函数源码,但我找到了一个方法。

报错中的 xxxxx.so 一般都位于 system/vendor/lib 中,因为用的是 lineage13.

在若依(Ruoyi框架中,菜单配置和路由参数的设置是非常重要的环节。以下是详细的步骤和注意事项: ### 1. 菜单配置 若依的菜单配置通常在数据库中进行,具体表为 `sys_menu`。在配置菜单时,需要注意以下几个字段: - `menu_name`:菜单名称 - `parent_id`:父级菜单ID - `order_num`:菜单顺序 - `path`:路由路径 - `component`:组件路径 - `perms`:权限标识 - `icon`:菜单图标 - `type`:菜单类型(目录、菜单、按钮) ### 2. 路由参数设置 在若依中,路由参数通常在 `path` 和 `component` 字段中设置。假设我们有一个菜单项需要跳转到某个页面,并且需要传递一些参数,可以按照以下步骤进行配置: #### 示例配置 假设我们要配置一个菜单项,路径为 `/example`,组件为 `example.vue`,并且需要传递一个参数 `id`。 1. **数据库配置**: ```sql INSERT INTO `sys_menu` (`menu_name`, `parent_id`, `order_num`, `path`, `component`, `perms`, `icon`, `type`) VALUES ('示例菜单', 0, 1, 'example', 'example', 'example:view', 'example', 1); ``` 2. **前端配置**: 在 `src/router/index.js` 中配置路由: ```javascript { path: 'example', name: 'Example', component: () => import('@/views/example/index.vue'), meta: { title: '示例菜单', icon: 'example' }, props: route => ({ id: route.query.id }) } ``` 3. **传递参数**: 在前端页面中,可以通过路由参数传递 `id`。例如,在菜单点击事件中: ```javascript this.$router.push({ path: '/example', query: { id: 123 } }); ``` ### 3. 页面接收参数 在 `example.vue` 页面中,可以通过 `props` 接收参数: ```vue <template> <div> <h1>示例页面</h1> <p>接收到的参数:{{ id }}</p> </div> </template> <script> export default { props: ['id'], mounted() { console.log('接收到的参数:', this.id); } } </script> ``` ### 注意事项 - 确保 `path` 和 `component` 字段正确配置。 - 使用 `props` 接收参数时,确保前后端配置一致。 - 传递参数时,可以通过 `query` 或 `params` 进行传递,具体根据需求选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值