一个ResourceNotFound Exception引发的思考

本文探讨了在大模式下启动相机导致crash的问题,并深入分析了资源未找到的原因。通过对Android源码的研究,揭示了资源查找机制及产品属性设置的影响。

问题背景:在大模式下启动相机,直接crash报了ResourceNotFound Exception。
在启动相机的过程中有一个资源Id没有找到,直接导致相机crash了。通过检查代码,发现该资源id在values-sw480dp目录下面已设置了,但是没有在values目录下面设置默认值,而我们产品默认取的资源就是在values-sw480dp-hdpi目录下面,那为什么没有找到该资源呢?屏幕的宽度是800,density为1.75,计算得出最小宽度值是457dp。计算公式如下所示:
sw(N)dp = 屏幕的宽度 / density
按照Android资源优先匹配规则,只会找小于等于457dp的资源目录,奇怪的是6月5号之前的版本为什么又可以呢,看来只能去源码中查看真相,在WindowManagerService类中找到计算尺寸大小和屏幕布局的方法。

private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated,
                  int dw, int dh, float density, Configuration outConfig) {
        // TODO: Multidisplay: for now only use with default display.

        // We need to determine the smallest width that will occur under normal
        // operation.  To this, start with the base screen size and compute the
        // width under the different possible rotations.  We need to un-rotate
        // the current screen dimensions before doing this.
        int unrotDw, unrotDh;
        if (rotated) {
            unrotDw = dh;
            unrotDh = dw;
        } else {
            unrotDw = dw;
            unrotDh = dh;
        }
        displayInfo.smallestNominalAppWidth = 1<<30;
        displayInfo.smallestNominalAppHeight = 1<<30;
        displayInfo.largestNominalAppWidth = 0;
        displayInfo.largestNominalAppHeight = 0;
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh);
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw);
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh);
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw);
        int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
        sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh);
        sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw);
        sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh);
        sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw);
**//计算最小宽度值**
        outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
        outConfig.screenLayout = sl;

跟踪代码发现在Configuration类里面,对smallestScreenWidthDp进一步做了处理:

//在产品属性里面设置ro.config.***值为true,是否锁定资源dpi,true表示锁定,false表示不锁定
Boolean isLockResMultiDpi = SystemProperties.getBoolean("ro.config.***",false);
if((isLockResMultiDpi && isMultiWhiteList()) || !isLockResMultiDpi){
    **//计算新的smallestNominalAppWidth**
    smallestNominalAppWidth = (smallestNominalAppWidth*dstDensity+srcDensity-1)/srcDensity;
}

在方法isMulitWhiteList()里面发现相机应用不在白名单里面,真相终于找到了。如果产品属性设置为false,无论显示模式为大中小,smallestNominalAppWidth都会被锁定为中间值;如果产品属性设置为true,另还要判断该应用是否加入白名单,如果加入白名单则锁定为中间值,否则就不会锁定,就会取默认值。
  遇到问题不能仅从应用层资源适配的角度去思考,还要从根源上找原因,从底层源码里找真相。

### 问题分析 在使用 ROS(Robot Operating System)时,运行 `roslaunch` 或 `roscore` 命令时出现 `Resource not found: roslaunch` 错误,通常表明系统无法找到所需的 ROS 包。这种问题可能由多个因素引起,包括包未正确安装、ROS 工作空间未正确配置、或环境变量未正确设置。 ### 解决方法 #### 1. 安装缺失的 ROS 包 如果提示 `Resource not found: roslaunch`,可以尝试手动安装 `roslaunch` 包: ```bash sudo apt install ros-noetic-roslaunch ``` 确保使用与当前 ROS 版本对应的包名,例如 `ros-<your_ros_version>-roslaunch`。 #### 2. 检查 ROS 包路径配置 ROS 使用 `ROS_PACKAGE_PATH` 环境变量来查找包。如果工作空间未正确配置,ROS 可能无法识别自定义包。可以在 `~/.bashrc` 文件中添加以下内容以确保路径正确: ```bash source /你的/ros工作空间路径/devel/setup.bash export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:~/你的/ros_ws/src ``` 随后更新环境变量: ```bash source ~/.bashrc ``` #### 3. 确保包命名规范 ROS 包名称必须以小写字母开头,并且只能包含字母、数字和下划线。如果遇到包名不规范问题,需修改包名、`CMakeLists.txt` 和 `package.xml` 文件中的名称,以确保一致性[^3]。 #### 4. 初始化和构建工作空间 确保 ROS 工作空间已初始化并正确构建: ```bash cd ~/catkin_ws catkin_make source devel/setup.bash ``` 如果工作空间路径不同,请替换为实际路径。 #### 5. 检查 ROS 安装完整性 如果上述方法无效,可能是 ROS 安装不完整。建议重新安装 ROS 核心组件: ```bash sudo apt install ros-noetic-desktop-full ``` 并确保初始化 `rosdep` 和设置环境变量: ```bash sudo rosdep init rosdep update ``` --- ### 示例代码 验证 `roslaunch` 是否安装成功: ```bash roslaunch --version ``` 如果输出类似 `roslaunch version 1.15.9`,则表示安装成功。 --- ### 相关问题 1. 如何在 Ubuntu 上安装 ROS 并配置环境变量? 2. ROS 中的 catkin 工作空间如何初始化? 3. 在 ROS 中运行 `rosrun` 时提示 `Command not found` 应该如何解决? 4. ROS 包命名规范有哪些要求? 5. 如何在 ROS 中正确设置 `ROS_PACKAGE_PATH`?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值