当前位置: 首页 > news >正文

Android14源码移植到Android16的应用报错分析说明

Android14源码移植到Android16的应用报错分析说明

文章目录

  • Android14源码移植到Android16的应用报错分析说明
    • 一、前言
    • 二、具体分析说明
      • 1、分析过程
      • 2、Android.bp属性分析修改
      • 3、某些具体代码规范修改示例
        • (1)未使用的方法和变量报错
        • (2)未定义final报错
        • (3)未定义static
        • (4)发送广播报错
        • (5)注释
    • 三、其他
      • 1、报错小结
      • 2、Android命名规范
      • 3、Android16 应用代码新特性
      • 4、Android.bp其他属性规范代码方式示例
        • (1)通过 `errorprone` 配置强制 Java 代码规范
        • (2)通过 `lint` 配置强制 Android 特定规范
        • (3)通过 `javacflags` 配置基础 Java 编译规范

一、前言

最近移植Android14的应用源码到Android16上面发现有报错。

移植的部分源码是系统Bluetooth应用的修改代码;普通的系统应用源码修改好像是没这些报错的。

主要报错内容有:未使用final,方法或者变量未使用,注释代码不正确等等编译异常。

这个些问题编译Error异常,是必须处理的,不能跳过,要适配代码或者环境。

为啥Android16中会报错?Android14的源码没有报错?

下面进行简单分析介绍,后续Android新版本源码可能会遇到相关的问题,可以参考修改。

二、具体分析说明

1、分析过程

不同源码的SKD版本肯定不同,难道是因为SDK版本问题?

但是思索过后发现,应该不是SDK问题,像是强制代码规范问题;

估计和Java版本的jdk有关?

//Android14的系统源码的Java版本默认是17
//jdk 17 没有强制代码规范问题
Android14_OS/release$ java --version
openjdk 17.0.4.1 2022-08-12
OpenJDK Runtime Environment Android_PDK (build 17.0.4.1+0-9205083)
OpenJDK 64-Bit Server VM Android_PDK (build 17.0.4.1+0-9205083, mixed mode, sharing)
Android14_OS/release$ //Android15和Android16的系统源码的Java版本默认是17
//这个jdk 21是问题的?
Android16_OS/release$ java --version
openjdk 21.0.1 2023-10-17
OpenJDK Runtime Environment Android_PDK (build 21.0.1+-11233762)
OpenJDK 64-Bit Server VM Android_PDK (build 21.0.1+-11233762, mixed mode, sharing)
Android16_OS/release$ 

但是Java规范应该很早以前就有了,所以不一定是Java版本问题。

大概猜测是Android.bp定义的某个属性字段的区别。

通过多个属性对比和修改,发现了确实是Android16某个属性导致代码强制规范。

相关的属性是:defaults: [“bluetooth_framework_errorprone_rules”],

2、Android.bp属性分析修改

不同源码定义的default规则代码有点差异:

//Android14 Bluetooth:
android_app {name: "Bluetooth",defaults: ["bluetooth-module-sdk-version-defaults"],//AN15 Bluetooth:
android_app {name: "Bluetooth",defaults: ["bluetooth_framework_errorprone_rules"],//AN16 Bluetooth:android_library {name: "BluetoothLib",
-    defaults: ["bluetooth_framework_errorprone_rules"],manifest: "LibAndroidManifest.xml",

上面是Android14-16的 Bluetooth 应用源码 packages\modules\Bluetooth\android\app\Android.mk 的部分区别。

可以看到Android14 定义的是bluetooth-module-sdk-version-defaults;

Android15和Android16 定义的是"bluetooth_framework_errorprone_rules;

具体的强制规范的内容,这里不进行探讨和研究。

Android16 在app编译中未定义default,但是他加载的默认库,是定义的default。

总之问题是找到了,如何修改?

尝试了把Android14的default放到16中编译,发现会编译失败,估计不兼容。

解决方法:

可以把 defaults 的整个属性去掉就可以规避这些编译报错。

因为我们自研的很多系统应用都是没加这个defaults属性的;

很少对于系统代码会进行强制规范。

但是平时开发的代码还是要进行代码规范比较好。

如果不想修改上面的Android.bp文件,可以慢慢修改代码规范问题,就可以编译通过了。

3、某些具体代码规范修改示例

(1)未使用的方法和变量报错

代码:

final int confirmIndex = cursor.getColumnIndexOrThrow(BluetoothShare.USER_CONFIRMATION);

上面是普通定义的代码。

报错:

packages/modules/Bluetooth/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java:329: error: [UnusedVariable] The local variable 'confirmIndex' is never read.
final int confirmIndex = cursor.getColumnIndexOrThrow(BluetoothShare.USER_CONFIRMATION);

解决:

删除或者暂时注释无用代码。

其他的方法或者方法内的变量未使用也是爆类似的错误。

(2)未定义final报错

代码:

private String TAG = "NotifyDialogManager";

报错:

error: [FieldCanBeFinal] This field is only assigned during initialization; consider making it final

解决:

private static final String TAG = "NotifyDialogManager"; //最后是加  static final

如果不需要暴露可以不加static

(3)未定义static

代码:

WindowManager.LayoutParams createLayoutParams() { }
private void updateCompletedNotification() { }

报错:

error: [MethodCanBeStatic] A private method that does not reference the enclosing instance can be static(see https://errorprone.info/bugpattern/MethodCanBeStatic)Did you mean 'static WindowManager.LayoutParams createLayoutParams() {'?
packages/modules/Bluetooth/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java:487: error: [MethodCanBeStatic] A private method that does not reference the enclosing instance can be staticprivate void updateCompletedNotification() {^(see https://errorprone.info/bugpattern/MethodCanBeStatic)Did you mean 'private static void updateCompletedNotification() {'?

解决: 添加static

(4)发送广播报错

这个好像是一个蓝牙的系统的广播,并不是所以的发送广播都会有这个报错。

代码:

mContext.sendBroadcast(new Intent(baseIntent).setAction(Constants.ACTION_DECLINE));

报错:

error: [AndroidFrameworkRequiresPermission] Failed to resolve broadcast intent action for validation
mContext.sendBroadcast(new Intent(baseIntent).setAction(Constants.ACTION_ACCEPT));

解决:

方式一:
在方法请添加备注进行规避:@SuppressLint("MissingPermission")方式二:
mContext.sendBroadcast(new Intent(baseIntent).setAction(Constants.ACTION_ACCEPT),"com.android.permission.RECEIVE_ACCEPT" // 与定义的权限一致
);方式三:
Intent intent = new Intent(baseIntent);
intent.setAction(Constants.ACTION_ACCEPT);
// 显式指定目标接收器的类名(确保接收器在当前应用中)
intent.setComponent(new ComponentName(mContext, YourReceiver.class));
mContext.sendBroadcast(intent); // 此时无需依赖 Action 匹配,Lint 不会报错方式四:
如果是本应用接收,使用本地广播
import androidx.localbroadcastmanager.content.LocalBroadcastManager;LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(baseIntent).setAction(Constants.ACTION_ACCEPT));

需要注意的是,发送这里修改成本地广播,注册监听的地方也要修改成本地广播的方式进行监听,无法会监听不到。

(5)注释

代码:

private test () {/** test message**/String tast = "a";
}

报错:

error: [NotJavadoc] Avoid using `/**` for comments which aren't actually Javadoc./** test message**/^(see https://errorprone.info/bugpattern/NotJavadoc)Did you mean '/* test message**/'?

解决:

把代码内部注释/** --- **/ 替换成 /*  -- */
第一种注释的方法前面的说明,第二种注释才是代码方法内的片段注释,主要用于多行说明的注释。

还有其他一些报错,根据报错内容进行修改就OK的,一般不会太难。

三、其他

1、报错小结

这里的报错都是Java的代码规范报错;有部分可能是安全规范报错;

后面新版本的Android源码可能会更多系统应用有代码规范的要求。

平时开发的时候多注意规范代码就可以避免大部分的问题了。

2、Android命名规范

Android程序开发中,使用规范的命名有益于程序的开发和后期阅读。

本文主要对Android程序包名的定义做详细介绍,并附带一些简单的命名规则:

https://blog.csdn.net/wenzhi20102321/article/details/61650405

3、Android16 应用代码新特性

Android 16 相对于 Android 15 和 14,在系统行为、[API 接口](https://so.csdn.net/so/search?q=API 接口&spm=1001.2101.3001.7020)、权限模型、性能优化等方面存在多处代码级差异,这些差异直接影响应用的兼容性和功能实现。

以下从核心场景对比具体代码变化,有兴趣的看看:

https://blog.csdn.net/wenzhi20102321/article/details/152091011

4、Android.bp其他属性规范代码方式示例

Android.bp除了上面的defaults,还是其他代码属性也是有规范代码的作用的,

但是不一定有用,需要自己验证编译,这里经供参考:

(1)通过 errorprone 配置强制 Java 代码规范
java_library {  // 或 android_library、java_binary 等模块类型name: "my_module",srcs: ["src/**/*.java"],// 配置 ErrorProne 静态检查errorprone: {javacflags: [// 1. 强制文档注释规范(如避免类似 Javadoc 但格式错误的注释)"-Xep:AlmostJavadoc:ERROR",// 2. 强制处理空指针风险(禁止对 @Nullable 变量直接调用方法)"-Xep:NullAway:ERROR","-XepOpt:NullAway:AnnotatedPackages=com.example",  // 指定检查的包// 3. 禁止未使用的变量、参数(减少冗余代码)"-Xep:UnusedVariable:ERROR","-Xep:UnusedParameter:ERROR",// 4. 禁止自动装箱/拆箱的冗余操作(如 Integer.valueOf(1) 可简化为 1)"-Xep:RedundantBoxing:ERROR",// 5. 禁止使用过时 API(强制替换为新 API)"-Xep:DeprecatedApi:ERROR",// 6. 强制 equals() 与 hashCode() 成对重写(避免集合操作异常)"-Xep:EqualsHashCode:ERROR",// 7. 禁止字符串常量拼接(如 "a" + "b" 应直接写 "ab")"-Xep:StringEquality:ERROR",],},
}
(2)通过 lint 配置强制 Android 特定规范
android_library {name: "my_android_module",srcs: ["src/**/*.java"],resource_dirs: ["res"],// 配置 Android Lint 检查lint: {// 1. 开启严格模式:所有 Lint 警告视为错误(阻断构建)strict: true,// 2. 仅启用指定的检查项(按需添加,更精准)checks: ["UnusedResources",  // 禁止未使用的资源(drawable、string等)"HardcodedText",    // 禁止硬编码文本(强制使用 string.xml)"LogUsage",         // 禁止在正式代码中使用 Log(需替换为日志框架)"ToastLength",      // 禁止 Toast 时长使用 LENGTH_LONG(避免用户体验问题)"AppCompatMethod",  // 强制使用 AppCompat 兼容方法(如 getSupportActionBar())],// 3. 排除特定检查项(可选,在 strict=true 时临时放宽)disable: ["TypographyDashes"],  // 暂时允许连字符不规范// 4. 配置检查的严重级别(如将某检查项设为错误)error: ["HardcodedText"],  // 即使 strict=false,也将硬编码文本设为错误},
}
(3)通过 javacflags 配置基础 Java 编译规范
java_library {name: "my_module",srcs: ["src/**/*.java"],// 基础 Java 编译规范javacflags: ["-Werror",  // 将所有编译器警告视为错误(强制修正所有警告)"-Xlint:unchecked",  // 检测未检查的类型转换(泛型相关)"-Xlint:deprecation",  // 检测使用过时 API 的警告"-Xlint:rawtypes",  // 禁止使用原始类型(如 List 而非 List<String>)],
}

不同的源码或者不同Android版本对于规范的属性可能不一定完全通用;

一般可以借鉴其他的系统源码应用的Android.bp规则进行对比修改。

http://www.dtcms.com/a/498998.html

相关文章:

  • 13万枚比特币被没收。。。
  • 企业网站规划案例网页微信版传输助手
  • 用Trae自动生成一个围棋小程序
  • 聊天室项目开发——etcd的安装和使用
  • 小林coding | MySQL图解
  • 大模型-智能体-【篇二:多智能体框架】
  • C语言文件操作全面解析:从基础概念到高级应用
  • 人大计算金融课程名称:《机器学习》(题库)/《大数据与机器学习》(非题库) 姜昊教授
  • 网站建设的策划文案设计公司网站公司详情
  • VMD-LSTM: 医疗时序数据降噪与预测优化课件分析(2025年6月教学版)
  • iOS Runtime之 KVO
  • ZigBee中的many-to-one和link status(1)
  • 【WRF-CMAQ第二期】WRF-CMAQ 测试案例安装与运行
  • 汕头seo网站排名免费制作网页的软件有哪些
  • 韩国设计网站推荐yandex搜索引擎入口
  • 2025年机器视觉软件平台哪个好?场景适配视角下的优质实例解析
  • 【C++/Lua联合开发】 (一) Lua基础知识
  • 从前序与中序遍历序列构造二叉树
  • 学习go语言
  • Linux中工作队列使用
  • 金融工程(一)
  • LeetCode 每日一题 2025/10/13-2025/10/19
  • C++ 面试基础考点 模拟题 力扣 38. 外观数列 题解 每日一题
  • 辽阳企业网站建设费用企业推广软文
  • 天津实体店网站建设深圳宝安区住建局官网
  • shell编程语言---sed
  • iframe实战:跨域通信与安全隔离
  • 购物网站的建设意义html可视化编辑软件
  • Bootstrap 字体图标
  • PVE 9.0 定制 Debian 13 镜像 支持 Cloud-Init 快速部署虚拟机【模板篇】