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

Android16 应用代码新特性

Android16 应用代码新特性

文章目录

  • Android16 应用代码新特性
      • 一、系统行为强制变更(代码适配差异)
        • 1. 全屏布局机制
        • 2. 预测返回导航
      • 二、权限模型重构(代码声明差异)
        • 1. 健康数据权限精细化
        • 2. 剪贴板访问权限
      • 三、API 接口重大变更(方法 / 类替换)
        • 1. 生物识别认证分级
        • 2. Nearby Share 传输升级
        • 3. 内存管理优化
      • 四、AI 与本地模型集成(新增 API)
      • 五、广播与事件机制(安全性增强)
        • 1. 动态广播导出状态强制声明
        • 2. 有序广播废弃
      • 六、开发者工具链(依赖与语法变更)
        • 1. Jetpack Compose 版本强制升级
        • 2. 编译工具要求
      • 七、总结:核心差异领域

Android16应用代码对比Android15、14有啥代码差异?

Android 16 相对于 Android 15 和 14,在系统行为、API 接口、权限模型、性能优化等方面存在多处代码级差异,这些差异直接影响应用的兼容性和功能实现。

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

一、系统行为强制变更(代码适配差异)

1. 全屏布局机制
  • Android 14/15:可通过windowOptOutEdgeToEdgeEnforcement

    禁用全屏布局:xml

    <!-- Android 14/15 可选配置 -->
    <style name="AppTheme"><item name="windowOptOutEdgeToEdgeEnforcement">true</item>
    </style>
    
    • Android 16:彻底移除该属性,所有应用默认强制全屏,需显式处理状态栏 / 导航栏遮挡:
kotlin:// Android 16 必须添加的适配代码
val windowInsetsController = ViewCompat.getWindowInsetsController(window.decorView)windowInsetsController?.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE// 布局中设置 padding 避免内容被遮挡ViewCompat.setOnApplyWindowInsetsListener(yourView) { view, insets ->val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())view.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)insets}Java:// Android 16 窗口布局适配import androidx.core.view.WindowInsetsControllerCompat;import androidx.core.view.ViewCompat;import androidx.core.graphics.Insets;import androidx.core.view.WindowInsetsCompat;// 配置系统栏行为WindowInsetsControllerCompat windowInsetsController = new WindowInsetsControllerCompat(getWindow(), getWindow().getDecorView());windowInsetsController.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
);windowInsetsController.hide(WindowInsetsCompat.Type.systemBars());// 处理布局内边距View rootView = findViewById(R.id.root_view);ViewCompat.setOnApplyWindowInsetsListener(rootView, (view, insets) -> {Insets bars = insets.getInsets(WindowInsetsCompat.Type.systemBars());view.setPadding(bars.left,bars.top,bars.right,bars.bottom);return insets;});
2. 预测返回导航
  • Android 14:仅手势导航支持预测返回,可通过onBackPressed() 兼容:

    kotlin
    // Android 14 旧逻辑
    override fun onBackPressed() {super.onBackPressed() // 直接触发返回
    }
    
  • Android 15:扩展至三键导航,但仍支持 onBackPressed() 降级;

  • Android 16:完全废弃onBackPressed() 和 KEYCODE_BACK

    强制使用新回调:

    kotlin:
    // Android 16 必须使用的新逻辑
    onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {override fun handleOnBackPressed() {// 处理返回逻辑(如弹窗确认)if (shouldFinish) finish()else isEnabled = false // 交给父级处理}
    })Java:// Android 16 返回导航import androidx.activity.OnBackPressedCallback;import androidx.lifecycle.LifecycleOwner;getOnBackPressedDispatcher().addCallback((LifecycleOwner) this, new OnBackPressedCallback(true) {@Overridepublic void handleOnBackPressed() {if (canGoBack()) {finish(); // 处理返回} else {showExitDialog(() -> setEnabled(false)); // 禁用回调,让系统处理}}private boolean canGoBack() {// 判断是否可返回的逻辑return false;}private void showExitDialog(Runnable onConfirm) {// 显示退出对话框,确认后调用 onConfirmonConfirm.run();}
    });
    

在Android16 demo和手机上测试了一下,onBackPressed()回调还是可以在Activity监听,但是左滑退出没有回调了;

getOnBackPressedDispatcher().addCallback 左滑退出是有回调的,说明之前的onBackPressed()已经废弃了。

二、权限模型重构(代码声明差异)

1. 健康数据权限精细化
  • Android 14/15:通过BODY_SENSORS

    统一申请健康传感器权限:

    xml
    <!-- Android 14/15 权限声明 -->
    <uses-permission android:name="android.permission.BODY_SENSORS" />
    
  • Android 16:拆分为 12 个细分权限,需按需声明:

    xml
    <!-- Android 16 权限声明 -->
    <uses-permission android:name="android.permission.READ_HEART_RATE" />
    <uses-permission android:name="android.permission.READ_BLOOD_PRESSURE" />
    <uses-permission android:name="android.permission.READ_HEALTH_DATA_IN_BACKGROUND" /> <!-- 后台访问需额外声明 -->
    

    代码中请求权限时也需对应调整:

    kotlin
    // Android 16 权限请求
    registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->if (permissions[Manifest.permission.READ_HEART_RATE] == true) {// 访问心率传感器}
    }.launch(arrayOf(Manifest.permission.READ_HEART_RATE))Java
    // Android 16 健康权限请求
    import androidx.activity.result.ActivityResultLauncher;
    import androidx.activity.result.contract.ActivityResultContracts;
    import android.Manifest;
    import android.content.pm.PackageManager;
    // 注册权限请求回调private final ActivityResultLauncher<String[]> requestHealthPermissions =registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), permissions -> {if (permissions.getOrDefault(Manifest.permission.READ_HEART_RATE, false)) {startHeartRateMonitoring();}});// 发起权限请求public void requestHeartRatePermission() {if (checkSelfPermission(Manifest.permission.READ_HEART_RATE) != PackageManager.PERMISSION_GRANTED) {requestHealthPermissions.launch(new String[]{Manifest.permission.READ_HEART_RATE});} else {startHeartRateMonitoring();}}private void startHeartRateMonitoring() {// 开始心率监测}
    
2. 剪贴板访问权限
  • Android 14/15:访问剪贴板无需特殊权限;

  • Android 16:必须申请READ_CLIPBOARD权限:

    xml
    <!-- Android 16 新增权限 -->
    <uses-permission android:name="android.permission.READ_CLIPBOARD" />
    

    代码中需先检查权限:

kotlin// Android 16 剪贴板访问逻辑if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CLIPBOARD) == PackageManager.PERMISSION_GRANTED) {val clipboard = getSystemService(ClipboardManager::class.java)val text = clipboard.primaryClip?.getItemAt(0)?.text}Java// Android 16 剪贴板访问
import android.content.ClipboardManager;import android.content.pm.PackageManager;
import android.Manifest;import androidx.core.content.ContextCompat;public String getClipboardText() {if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CLIPBOARD)!= PackageManager.PERMISSION_GRANTED) {// 未获得权限,请求权限或提示用户return null;}ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);if (clipboard != null && clipboard.getPrimaryClip() != null && clipboard.getPrimaryClip().getItemCount() > 0) {return clipboard.getPrimaryClip().getItemAt(0).getText().toString();}return null;}

三、API 接口重大变更(方法 / 类替换)

1. 生物识别认证分级
  • Android 14/15:通过 BIOMETRIC_STRONG

    标识强认证:

kotlin// Android 14/15 生物识别val promptInfo = BiometricPrompt.PromptInfo.Builder().setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG).build()
  • Android 16:引入 L1-L3 分级,支付场景强制 L3 级:

    kotlin
    // Android 16 生物识别分级
    val promptInfo = BiometricPrompt.PromptInfo.Builder().setAuthenticationLevel(BiometricManager.Authenticators.BIOMETRIC_LEVEL_3) // L3 活体检测.build()Java// Android 16 生物识别分级
    import androidx.biometric.BiometricPrompt;import androidx.core.content.ContextCompat;
    import java.util.concurrent.Executor;private void showBiometricPrompt() {Executor executor = ContextCompat.getMainExecutor(this);BiometricPrompt biometricPrompt = new BiometricPrompt(this, executor,new BiometricPrompt.AuthenticationCallback() {@Overridepublic void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {super.onAuthenticationSucceeded(result);// 认证成功处理}});BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder().setTitle("确认支付")// 设置 L3 级认证(最高安全级).setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_LEVEL_3).build();biometricPrompt.authenticate(promptInfo);
    }
2. Nearby Share 传输升级
  • Android 14/15:使用旧版 API 单设备传输:
// Android 14/15 传输文件
Nearby.getShareClient(context).send(uri, deviceId).addOnSuccessListener { /* 处理成功 */ }
  • Android 16:新增多设备并行传输 API(需 Wi-Fi 7 支持):
  kotlin// Android 16 多设备传输val transfer = Nearby.getShareClient(context).createMultiDeviceTransfer(listOf(uri1, uri2), listOf(device1, device2))transfer.start().addOnSuccessListener { /* 处理成功 */ }
3. 内存管理优化
  • Android 14/15:默认 4KB 内存页,无显式配置;

  • Android 16:支持 16KB 内存页,旧应用需兼容:

    xml
    <!-- Android 16 如需保留 4KB 页(不推荐) -->
    <application android:pageSizeCompat="4k" />
    

    代码中可判断设备支持类型:

    kotlin
    // Android 16 内存页适配
    if (Build.VERSION.SDK_INT >= 36) {val pageSize = ActivityManager.getMemoryPageSize()if (pageSize == 16384) { // 16KB// 启用优化逻辑}
    }Java// Android 16 内存页适配
    import android.app.ActivityManager;import android.content.Context;
    import android.os.Build;import androidx.annotation.RequiresApi;@RequiresApi(api = Build.VERSION_CODES.JAVA16)
    private void adaptToMemoryPageSize() {ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);int pageSize = activityManager.getMemoryPageSize();if (pageSize == 16384) { // 16KB 内存页// 启用大内存块优化逻辑optimizeForLargePages();} else {// 兼容 4KB 内存页的逻辑compatibilityWithSmallPages();}}private void optimizeForLargePages() {// 针对 16KB 内存页的优化
    }private void compatibilityWithSmallPages() {// 兼容 4KB 内存页的逻辑}
    

四、AI 与本地模型集成(新增 API)

  • Android 14/15:无系统级本地大模型 API;

  • Android 16:新增 Gemini Nano 本地模型接口:

kotlin// Android 16 调用本地 AI 生成图片描述
val gemini = GeminiSession.getInstance(context)val image = ImageDecoder.decodeBitmap(...)
gemini.generateAltText(image).addOnSuccessListener { altText ->// 用于无障碍标签或图片搜索imageView.contentDescription = altText}Java// Android 16 本地 AI 集成
import android.graphics.Bitmap;import android.net.Uri;import android.os.Build;import androidx.annotation.RequiresApi;import com.google.android.gms.gemini.GeminiSession;import com.google.android.gms.tasks.OnSuccessListener;@RequiresApi(api = Build.VERSION_CODES.JAVA16)private void generateImageDescription(Uri imageUri) {try {// 解码图片Bitmap image = ImageDecoder.decodeBitmap(ImageDecoder.createSource(getContentResolver(), imageUri));// 获取 Gemini 实例GeminiSession gemini = GeminiSession.getInstance(getApplicationContext());// 生成图片描述gemini.generateAltText(image).addOnSuccessListener(altText -> {// 设置无障碍描述ImageView imageView = findViewById(R.id.image_view);imageView.setContentDescription(altText);});} catch (Exception e) {e.printStackTrace();}}

五、广播与事件机制(安全性增强)

1. 动态广播导出状态强制声明
  • Android 14:动态注册广播未指定导出状态时默认导出,无报错;

  • Android 15:未指定时抛出警告;

  • Android 16:未指定时直接抛出 IllegalArgumentException,必须显式声明:

    kotlin
    // Android 16 动态广播注册(必须指定导出状态)
    registerReceiver(myReceiver,IntentFilter("com.example.ACTION"),Context.RECEIVER_EXPORTED // 或 RECEIVER_NOT_EXPORTED
    )Java// Android 16 动态广播注册
    import android.content.BroadcastReceiver;import android.content.IntentFilter;
    import android.content.Context;private void registerMyReceiver() {BroadcastReceiver myReceiver = new MyReceiver();IntentFilter filter = new IntentFilter("com.example.ACTION");// 必须显式指定导出状态registerReceiver(myReceiver,filter,Context.RECEIVER_EXPORTED // 或 Context.RECEIVER_NOT_EXPORTED);}private class MyReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// 处理广播}}
    
2. 有序广播废弃
  • Android 14/15:仍可使用 sendOrderedBroadcast()

  • Android 16:标记为废弃,建议改用WorkManager:

kotlin// Android 16 替代有序广播的方案
WorkManager.getInstance(context).beginWith(FirstWorker::class.java).then(SecondWorker::class.java) // 按顺序执行.enqueue()Java
/ Android 16 WorkManager 替代有序广播import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;import java.util.Arrays;private void executeOrderedTasks() {// 第一步任务OneTimeWorkRequest firstWork = new OneTimeWorkRequest.Builder(FirstWorker.class).build();// 第二步任务(依赖第一步)OneTimeWorkRequest secondWork = new OneTimeWorkRequest.Builder(SecondWorker.class).build();// 按顺序执行WorkManager.getInstance(this).beginWith(firstWork).then(secondWork).enqueue();}// 定义 Worker 类
import androidx.work.Worker;import androidx.work.WorkerParameters;public class FirstWorker extends Worker {public FirstWorker(Context context, WorkerParameters params) {super(context, params);}@Overridepublic Result doWork() {// 执行第一步任务return Result.success();}}public class SecondWorker extends Worker {public SecondWorker(Context context, WorkerParameters params) {super(context, params);}@Overridepublic Result doWork() {// 执行第二步任务return Result.success();}}

六、开发者工具链(依赖与语法变更)

1. Jetpack Compose 版本强制升级
  • Android 14/15:支持 Compose 1.x/2.x;

  • Android 16:强制使用 Compose 3.0,部分 API 不兼容:

    kotlin
    // Android 14/15 旧列表组件
    LazyColumn {items(dataList) { item -> Text(item) }
    }
    // Android 16 新列表组件(性能优化)LazyColumnV2 {items(dataList) { item -> Text(item) }}
    
2. 编译工具要求
  • Android 14/15:最低支持 AGP 7.0;

  • Android 16:最低要求 AGP 8.5,且必须使用 Java 17 编译:

 gradle// Android 16 模块级 build.gradle 配置
android {compileSdk 36buildToolsVersion "36.0.0"compileOptions {sourceCompatibility JavaVersion.VERSION_17targetCompatibility JavaVersion.VERSION_17}}

七、总结:核心差异领域

维度Android 14/15 状态Android 16 变更点
系统行为可禁用全屏、支持旧返回逻辑强制全屏、废弃 onBackPressed()
权限模型健康数据 / 剪贴板无细分权限权限精细化、新增 READ_CLIPBOARD
核心 API生物识别单级、单设备传输生物识别分级、多设备传输 API
性能优化4KB 内存页、传统调度16KB 内存页、Project Quantum 引擎
AI 集成无系统级本地模型新增 Gemini Nano 接口
开发工具支持旧版 Compose/AGP强制 Compose 3.0、AGP 8.5、Java 17

适配时需重点关注权限声明更新系统行为强制变更废弃 API 迁移

建议结合官方迁移工具(如 Android Studio 的 lint 检查)批量定位代码差异点。

总的来说感觉变更Android16后,需要适配的实际代码很少,

因为很多功能基本没啥用过,比如AI集成,性能优化,生物识别等,都是不常用的;

返回按键那个功能是要适配一下的,毕竟之前的回调方法没用了,要用新的api方法了。

Android16还有另外的差异吗,肯定是有的,比如系统HIDL在Android16不支持了!那咋搞?

要用AIDL。 Android11新增了可以绑定底层的AIDL (C++ 绑定) 功能适配。

这个算是系统代码实现差异;另外说明。

本文的主要内容,算是应用代码功能使用差异。

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

相关文章:

  • 哪个网站做h5好小程序注册的账号怎么注销
  • 网站怎样做快照是做网站编辑还是做平面设计
  • 做好网站建设和运营秦皇岛建筑
  • 网站建设维护招聘一个新手如何做网站
  • 深圳网站建设做微信的网站叫什么软件
  • 惠州网站建设教程wordpress企业网站插件
  • 快应用报错Module Error 分包要求 app.json#minPlatformVersion 不小于 1061, 当前值为 21解决方案-优雅草卓伊凡
  • 做网站空间备案的职业wordpress 投稿 加标签
  • 网站建设外包工作怎么知道网站的ftp
  • 网站查询域名解析ip接单网站开发
  • 美发企业网站建设价格有网站和无网站的区别
  • 外贸关键词网站南昌开发公司
  • 电商网站设计文档网络工程师高级职称
  • 备案网站名怎么填写丽水微信网站建设报价
  • 32位汇编:实验4传送类指令的使用
  • MP4和WMV2压缩机制对比
  • 网站 图片延时加载农家院网站素材
  • 做网站包括什么条件网络游戏行业防沉迷自律公约
  • 17软件测试用例设计方法-决策表
  • 做英文行程的网站wordpress收费阅读插件
  • 网站建设技术难点wordpress评分管理
  • el-tooltip数据刷新之后没有显示tip提示
  • Ansible Playbook 编写指南:从入门到 Roles 模块化
  • 合成记录中声波时差的作用和常见取值
  • 整体设计 逻辑拆解之4 分布式架构设计:三次工程进阶(初始化/序列化/谱系化)的服务器协同方案
  • 成都建设网站公司哪家好2019个人建网站
  • 服务器与网站吗中企动力福利待遇好吗
  • 装饰公司看的设计网站电商网站seo公司
  • 旋转力学中的“坐标系优化”:深入浅出理解惯性主轴
  • wordpress网站网页加密网站建设的比较合理的流程