Android14(U)适配攻略

1. 升级编译环境

开发环境

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

准备Flamingo 或者最新Bate 版本的Android Studio

准备Android 14 的设备((https://developer.android.google.cn/about/versions/14/devices?hl=zh-cn))

gradle配置

classpath 'com.android.tools.build:gradle:8.0.0'

distributionUrl=https://services.gradle.org/distributions/gradle-8.0.0-bin.zip

设置Android 14 SDK

android {

    compileSdkPreview = "UpsideDownCake"

    ...

    defaultConfig {

        targetSdkPreview = "UpsideDownCake"

    }

}

生成BuildConfig和AIDL 关联文件

buildFeatures {

    buildConfig = true

    aidl = true

}

R文件传递

android.nonTransitiveRClass=false

View的id区分时使用Switc case

使用 if()else if() 替换 switch  case  或者在Gradle.properties中添加android.nonFinalResIds=false

设置命名空间:删除Manifest下的package标签,将包名信息添加到gradle的android路径下

android {

     namespace = "com.xx.xx"

 }

 项目中使用CompileOnly 编译的库需要在混淆文件中添加间接引用的类

TargetSdkVersion >=34的修改

对隐式 intent 和待处理 intent 的限制

对于以 Android 14 为目标平台的应用,Android 会通过以下方式限制应用向内部应用组件发送隐式 intent:

  • 隐式 intent 只能传送到导出的组件。应用必须使用显式 intent 传送到未导出的组件 带包名的去跳转,或将该组件标记为已导出。
  • 如果应用通过未指定组件或软件包的 intent 创建可变待处理 intent,系统现在会抛出异常。

这些变更可防止恶意应用拦截意在供应用内部组件使用的隐式 intent。

1

2

3

4

5

6

7

8

9

10

11

12

<activity

    android:name=".AppActivity"

    android:exported="false"> //false 不可导出 true可导出

    <intent-filter>

        <action android:name="com.example.action.APP_ACTION" />

        <category android:name="android.intent.category.DEFAULT" />

    </intent-filter>

</activity>

Intent explicitIntent =new Intent("com.example.action.APP_ACTION")

//跳转不可导出,需要设置包名

explicitIntent.setPackage(context.getPackageName());

context.startActivity(explicitIntent);

在运行时注册的广播接收器必须指定导出行为

在 Android 14 上,运行时通过 Context#registerReceiver() 动态注册广播接收器,需要设置标记 RECEIVER_EXPORTED 或 RECEIVER_NOT_EXPORTED ,标识是否导出该广播,避免应用程序出现安全漏洞,如果注册的是系统广播,则不需要指定标记。

三方SDK兼容修改方式:

如果三方SDK适配困难可以先在Activity或者Application中复写广播注册方法,如果有未添加是否可导出标记可以手动添加上

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

@Override

public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter) {

        return registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED或者Context.RECEIVER_NOT_EXPORTED);

    }

@Override

public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter, int flags) {

    Intent intent=null;

    try {

            boolean flagExported = (flags & Context.RECEIVER_EXPORTED) != 0;

            boolean flagNotExported = (flags & Context.RECEIVER_NOT_EXPORTED) != 0;

            if(!flagExported && !flagNotExported){

               intent = super.registerReceiver(receiver, filter, flags|Context.RECEIVER_EXPORTED或者Context.RECEIVER_NOT_EXPORTED);   

               return intent;

            }

        intent = super.registerReceiver(receiver, filter,flag);

    } catch (Throwable e) {

    }

    return intent;

}

。。。。。其他多参方法补上EXPORTED 参数

安全的动态代码加载(插件化/热更新)

new DexClassLoad(x,x,x,)
DexFile.loadFile(x) 都会抛异常

在动态文件(例如 DEX、JAR 或 APK 文件)打开并写入任何内容之前立即将其设为只读,插件化、热修复涉及ClassLoad去加载代码的地方,如果文件有写权限会立即报错。

将新下载的文件属性修改成只读文件,如果是已存在的文件最好可以先删除然后重新下载并且设置只读权限。

1

2

3

4

5

6

7

8

9

10

11

12

13

public static void modifyFileOnlyRead(String apkPath) {

    if (Util.isAndroidU()) {

        try {

            File file = new File(apkPath);

            boolean b = file.setReadOnly();

            if (file.canWrite()) {

                Runtime.getRuntime().exec("chmod 400 " + apkPath);

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

压缩路径遍历

对于以 Android 14 为目标平台的应用,Android 会通过以下方式防止 Zip 路径遍历漏洞:如果 Zip 文件条目名称包含“..”或以“/”开头,ZipFile(String) 和 ZipInputStream.getNextEntry() 会抛出 ZipException

应用可以通过调用 dalvik.system.ZipPathValidator.clearCallback() 选择停用此验证。

从后台启动Activity的附加限制

系统进一步限制了应用在后台启动 Activity 的时间:

  • 当应用使用 PendingIntent#send() 发送 PendingIntent 以及类似行为时,如果应用想要授予其自己的后台 service 启动权限以启动 pending intent,则该应用现在必须选择加入一个 ActivityOptions,具体为带有 setPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
  • 当一个可见应用使用 bindService() 绑定另一个在后台运行的应用的服务时,如果该可见应用想要将其自己的后台 activity 启动权限授予绑定服务,则它现在必须选择加入 BIND_ALLOW_ACTIVITY_STARTS 标志。

启动前台服务必须设置前台服务类型

如果有使用startForeground() 在清单文件中必须要指定服务的前台类型,例如音频播放类的可以使用mediaPlayback

为了帮助开发者更有目的地定义面向用户的前台服务,Android 10 在 <service> 元素内引入了 android:foregroundServiceType 属性。

如果您的应用以 Android 14 为目标平台,则必须指定适当的前台服务类型。与以前的 Android 版本一样,可组合使用多个类型。下面列出了可供选择的前台服务类型:

  • camera
  • connectedDevice
  • dataSync
  • health
  • location
  • mediaPlayback
  • mediaProjection
  • microphone
  • phoneCall
  • remoteMessaging
  • shortService
  • specialUse
  • systemExempted

如果应用中的用例与这些类型均不相关,强烈建议您迁移逻辑以使用 WorkManager 或用户发起的数据传输作业。

Android 14 中新增了 health, remoteMessaging, shortService, specialUse 和 systemExempted 类型。

以下代码段提供了一个清单中的前台服务类型声明示例:

1

2

3

4

5

6

7

8

9

10

11

<manifest ...>

  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />

    <application ...>

      <service

          android:name=".MyMediaPlaybackService"

          android:foregroundServiceType="mediaPlayback"

          android:exported="false">

      </service>

    </application>

</manifest>

如果以 Android 14 为目标平台的应用未在清单中定义给定服务的类型,系统会在调用 startForeground() 时引发 MissingForegroundServiceTypeException

Open JDK 17

Android 14 将继续更新 Android 的核心库,以与最新 OpenJDK LTS 版本中的功能保持一致,包括适合应用和平台开发者的库更新和 Java 17 语言支持。

以下变更可能会影响应用兼容性:

  • 对正则表达式的更改:现在,为了更严格地遵循 OpenJDK 的语义,不允许无效的组引用。您可能会看到 java.util.regex.Matcher 类抛出 IllegalArgumentException 的新情况,因此请务必测试应用中使用正则表达式的情形。如需在测试期间启用或停用此变更,请使用兼容性框架工具切换 DISALLOW_INVALID_GROUP_REFERENCE 标志。
  • UUID 处理:现在,验证输入参数时,java.util.UUID.fromString() 方法会执行更严格的检查,因此您可能会在反序列化期间看到 IllegalArgumentException。如需在测试期间启用或停用此变更,请使用兼容性框架工具切换 ENABLE_STRICT_VALIDATION 标志。
  • ProGuard 问题:有时,在您尝试使用 ProGuard 缩减、混淆和优化应用时,添加 java.lang.ClassValue 类会导致问题。问题源自 Kotlin 库,该库会根据 Class.forName("java.lang.ClassValue") 是否会返回类更改运行时行为。如果您的应用是根据没有 java.lang.ClassValue 类的旧版运行时开发的,则这些优化可能会将 computeValue 方法从派生自 java.lang.ClassValue 的类中移除。

Android 14 中有关限制非 SDK 接口的更新

非SDK API 表 (官网下载文件)

使用 Lint工具检查

TargetSdkVersion >=33的修改

默认拒绝设定精确的闹钟

 Android 14 开始 ,targetSdkVersion>=33的新安装用户 SCHEDULE_EXACT_ALARM 权限默认拒绝,在使用

  • setExact()
  • setExactAndAllowWhileIdle()
  • setAlarmClock()

时,APP会抛出异常,可在调用上述方法之前使用 canScheduleExactAlarms()

判断是否有闹钟权限,并且设置AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED 监听前台广播并对其做出正确反应 ,系统会在用户授予权限时发送该广播。

三种种方式修改:

1

2

3

4

5

6

public static void openAlarmPage(Context context){

    //可定义广播监听 SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED  是否开启

    Intent intent = new Intent();

    intent.setAction(ACTION_REQUEST_SCHEDULE_EXACT_ALARM);

    context. startActivity(intent);

}

  • Menifest申明<uses-permission android:name="android.permission.USE_EXACT_ALARM" />这个普通权限不需要运行时申请,但是需要注意隐私声明

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    public void start () {          

         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

             alarmManager.setExact(xxx, xxx, "TAG", new AlarmManager.OnAlarmListener() {

                     @Override

                     public void onAlarm() {         

                         start();

                     }

                 }, xx);

                 }

             }

授予对照片和视频的部分访问权限

只授予所选中媒体文件的权限

针对Android 13 及以上用户 Android 14 以上新增的权限 READ_MEDIA_VISUAL_USER_SELECTED 仅允许授予选中媒体文件的访问权限。如需要访问所有媒体文件需要同步申请READ_MEDIA_IMAGES 和 READ_MEDIA_VIDEO .

TargetSdkVersion==xxx 不区分版本对所有应用的更改

TargetSdkVersion<23的应用无法在Android U上安装

安全性,降低低版本权限问题导致APP数据泄露,升级TargetSdkVersion >=23

1

INSTALL_FAILED_DEPRECATED_SDK_VERSION: App package must target at least SDK version 23, but found 7

如果需要调试低版本Target的APP可以使用命令行安装

1

adb install --bypass-low-target-sdk-block app.apk

应用进入缓存时,上下文注册的广播将加入队列

应用进入缓存状态(例如进入后台) 上下文注册的广播会加入队列,等待应用退出缓存状态时,会一次性将多个在缓存队列的广播一次性发送, 存在广播合并的情况, 例如监听屏幕开启/关闭/开启/关闭, 应用只能接受开启-关闭 中间的状态会丢失.,广播也可能由于系统原因会从缓存队列删除. 此项变更让广播接收变得不那么靠谱,可能会导致APP资源得不到销毁引起内存泄露

应用只能终止自己的后台进程

从 Android 14 开始,当您的应用调用 killBackgroundProcesses() 时,该 API 只能终止您自己应用的后台进程。(影响第三方杀进程的应用例如(360手机卫士))

用户可以关闭不可关闭的通知

这项变更适用于通过 Notification.Builder#setOngoing(true) 或 NotificationCompat.Builder#setOngoing(true) 设置 Notification.FLAG_ONGOING_EVENT 来阻止用户关闭前台通知的应用。FLAG_ONGOING_EVENT 的行为已发生变化,使用户实际上能够关闭此类通知。

在以下情况下,此类通知仍不可关闭:

  • 当手机处于锁定状态时
  • 如果用户选择全部清除通知操作(有助于防止意外关闭)

此外,这一新行为不适用于以下用例中的不可关闭通知:

  • 使用 MediaStyle 创建的通知(notification.setStyle(ew NotificationCompat.MediaStyle()))

  • 安全和隐私用例的政策限制使用

  • 企业设备政策控制器 (DPC) 和支持软件包

新增、改善功能

截屏监听

添加权限: 可以监听截屏但是截屏文件还需要使用常规方法自己获取

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />

final Activity.ScreenCaptureCallback screenCaptureCallback =

    new Activity.ScreenCaptureCallback() {

        @Override

        public void onScreenCaptured() {

            // Add logic to take action in your app.

        }

    };

@Override

protected void onStart() {

    super.onStart();

    // Pass in the callback created in the previous step

    // and the intended callback executor (e.g. Activity s mainExecutor).

    registerScreenCaptureCallback(executor, screenCaptureCallback);

}

@Override

protected void onStop() {

    super.onStop();

    unregisterScreenCaptureCallback(screenCaptureCallback);

}

禁止当前ACtivity截屏可以添加下面的flag

1

activity.getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);

Path 路径可查询过程中的点位信息

Android 的 Path API 是一种强大且灵活的机制,可用于创建和渲染矢量图形,能够描边或填充路径,根据线段、二次曲线或立方曲线构建路径,执行布尔运算以获取更复杂的形状,或同时执行所有这些操作。但是无法了解 Path 对象中实际包含的内容;该对象的内部信息在创建后对于调用方是不透明的。

如需创建 Path,可以调用 moveTo()lineTo() 和 cubicTo() 等方法来添加路径片段。但无法询问该路径有哪些片段,因此必须在创建时保留该信息。

从 Android 14 开始,可以查询路径以了解其内部内容。首先,需要使用 Path.getPathIterator API 获取 PathIterator 对象:

1

2

3

Path path = new Path();path.moveTo(1.0F, 1.0F);

path.lineTo(2.0F, 2.0F);path.close();

PathIterator pathIterator = path.getPathIterator();

接下来,可以调用 PathIterator 逐个遍历片段,并检索每个片段的所有必要数据。以下示例使用了 PathIterator.Segment 对象,它会打包数据

1

2

while (pathIterator.hasNext()) { PathIterator.Segment segment = pathIterator.next();

Log.i(LOG_TAG, "segment: " + segment.getVerb() + ", " + segment.getPoints());}

PathIterator 还有一个非分配版 next(),可以在其中传入缓冲区来保存点数据。

查询 Path 数据的一个重要用例是插值。例如,大家可能想在两个不同的路径之间添加动画(或变形)。为了进一步简化该用例,Android 14 针对 Path 还有一个新的 interpolate() 方法。假设两个路径具有相同的内部结构,interpolate() 方法会使用该插值结果创建一个新的 Path。以下示例返回了一个形状介于 path 和 otherPath 之间的一半(线性插值为 0.5)的路径:

1

2

3

4

Path interpolatedResult = new Path();

if (path.isInterpolatable(otherPath)) {   

    path.interpolate(otherPath, 0.5F, interpolatedResult);

}

单应用语言偏好/语法优化/地区偏好

功能和 API 概览  |  Android 开发者  |  Android Developers (google.cn)

位置权限新增标签描述

权限弹窗是会显示描述信息,需要在清单文件中添加

1

2

3

4

在应用的资源目录/etc/ASL/asl-locations.xml新增配置,

<ASL-locations>

<ASL  package="com.xx.xx">【Path to ASL XML} </ASL>

</ASL-locations>

新增用户初始化Job权限RUN_USER_INITIATED_JOBS

Android 14 引入了android.permision.RUN_USER_INITIATED_JOBS权限,允许一个应用执行用户初始化Job权限,此权限可以被用手动关闭或者被系统撤销,应用需要targestsdk升级到U后来请求此权限

新增唤醒屏幕权限

Android 14 引入了android.permision.TURN_SCREEN_ON权限,目标平台为Android 14及以上的应用使用唤醒屏幕时,需要在AndroidManifest文件中配置这个权限。另外唤醒屏幕权限有一个对应的appops权限AppOpsManager.OP_TURN_SCREEN_ON,这个权限在Android T上是默认开启,在Android U上对目标平台为Android 14及以上的应用默认关闭。

不申请权限调用下面API 没有效果无法唤醒屏幕

1

2

3

4

5

PowerManager powerManager = (PowerManager) Context.getSystemService(

Context.POWER_SERVICE);

PowerManager.WakeLock wakeLock = powerManager.newWakeLock(

PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "testName");

wakeLock.acquire(3000)

字体放大可以到200%

功能和 API 概览  |  Android 开发者  |  Android Developers (google.cn)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/123921.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

音视频开发常见问题(四):视频花屏和绿屏

摘要 本文介绍了视频视频花屏/绿屏问题的常见原因&#xff0c;如丢失关键帧、metadata的变化、硬件编解码的兼容性问题和颜色格式不一致问题。以及排查方法和解决策略&#xff0c;包括检查视频数据格式、排查自采集/自渲染模块问题、联系第三方音视频SDK技术支持等。最后&…

kubernets挑战实验一(| pvc | pod | services | rolebinding | context)

参考&#xff1a; https://kubernetes.io/zh-cn/docs/tasks/access-application-cluster/configure-access-multiple-clusters/ Deploy the given architecture diagram for implementing a Jekyll SSG. 1、创建pvc使用,以下条件限制 Storage Request: 1Gi Access modes: Re…

【WSL 2】Windows10 安装 WSL 2,并配合 Windows Terminal 和 VSCode 使用

【WSL 2】Windows10 安装 WSL 2&#xff0c;并配合 Windows Terminal 和 VSCode 使用 1 安装 Windows Terminal2 安装 WSL 23 在 Windows 文件资源管理器中打开 WSL 项目4 在 VSCode 中使用 WSL 24.1 必要准备4.2 从 VSCode 中 Connect WSL4.3 从 Linux 中打开 VSCode 1 安装 W…

✔ ★【备战实习(面经+项目+算法)】 10.29学习

✔ ★【备战实习&#xff08;面经项目算法&#xff09;】 坚持完成每天必做如何找到好工作1. 科学的学习方法&#xff08;专注&#xff01;效率&#xff01;记忆&#xff01;心流&#xff01;&#xff09;2. 每天认真完成必做项&#xff0c;踏实学习技术 认真完成每天必做&…

企业微信接入芋道SpringBoot项目

背景&#xff1a;使用芋道框架编写了一个数据看板功能需要嵌入到企业微信中&#xff0c;方便各级人员实时观看 接入企业微信的话肯定不能像平常pc端一样先登录再根据权限看页面&#xff0c;不然的话不如直接手机浏览器打开登录账号来得更为方便&#xff0c;所以迎面而来面临两…

在CentOS上用yum方式安装MySQL8过程记录

此文参考官方文档一步一步记录安装到正常运行全过程 安装环境&#xff1a;centos7 mysql版本&#xff1a;8.0.35 安装过程主要参考下面两边文章&#xff1a; 1.官方文档 https://dev.mysql.com/doc/refman/8.0/en/linux-installation-yum-repo.html 2.linux yum安装mysql8 安…

Netty 使用和常用组件

简述 <dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId<version>4.1.42.Final </version><scope>compile</scope> </dependency>Netty 的优势 1、API 使用简单&#xff0c;开发门槛低&a…

css写个三角形

点击三角形&#xff0c;展开或者收起内容 <template><div><div class"zhankai" click"btn()">展开 <span :class"{sanjiao:true,rotate:flag}"></span></div><!-- 展示或者收起 --><el-collapse-…

Go 开发IDE全览:GoLand VS VSCode全面解析

一、引言 在软件开发的世界里&#xff0c;开发环境的选择与配置是成功项目的基础之一。特别是在Go&#xff08;又名Golang&#xff09;这样一个逐渐获得主流认同、在微服务和云计算领域有着广泛应用的编程语言中&#xff0c;选择合适的开发工具就显得尤为重要。虽然Go语言自身…

博通BCM575系列 RDMA 网卡驱动 bnxt_re 分析(一)

简介 整个BCM系列驱动分成以太网部分(bnxt_en.ko)和RDMA部分(bnxt_re.ko), 两个模块之间通过内核的auxiliary_bus进行管理.我们主要分析下bnxt_re驱动. 代码结构 这个驱动的核心是 qplib_fp.c, 这个文件主要包含了驱动的数据路径, 包括Post Send, Post Recv, Poll CQ流程的实…

Android NDK开发详解之Application.mk探秘

Android NDK开发详解之Application.mk探秘 概览变量APP_ASFLAGSAPP_ASMFLAGSAPP_BUILD_SCRIPTAPP_CFLAGSAPP_CLANG_TIDYAPP_CLANG_TIDY_FLAGSAPP_CONLYFLAGSAPP_CPPFLAGSAPP_CXXFLAGSAPP_DEBUGAPP_LDFLAGSAPP_MANIFESTAPP_MODULESAPP_OPTIMAPP_PLATFORMAPP_PROJECT_PATHAPP_STL…

Amaon CloudFront助力出海业务访问优化

企业的展示网站需要面向多个国家的客户时&#xff0c;由于地理位置的原因。往往会出现一个痛点&#xff0c;网络延迟太高&#xff0c;以至于图片、视频播放时会非常卡顿。客户的访问体验非常差&#xff0c;直接影响到企业收益。此篇文章九河云综合分析Amaon CloudFront&#xf…

matplotlib论文图片配色

还在为配图的颜色而烦恼嘛&#xff0c;还在为matplotlib的经典颜色而困惑嘛&#xff0c;看完下面的文章&#xff0c;教你如何选择图片颜色 上图左边是matplotlib默认的颜色系统&#xff0c;而右边就是使用matplotlib自带的颜色系统实现的。如何实现&#xff0c;请继续往下浏览 …

ES6中Map集合

Map集合是一个新的数据结构&#xff0c;它可以存储键值对&#xff0c;并且可以使用任何类型的值作为键&#xff0c;包括对象、数组和函数。Map也是一种可迭代的结构&#xff0c;可以使用for...of循环遍历。 在ES6中&#xff0c;我们可以使用Map构造函数来创建一个Map集合&…

当面试问你接口测试时,不要再说不会了

很多人会谈论接口测试。到底什么是接口测试&#xff1f;如何进行接口测试&#xff1f;这篇文章会帮到你。 前端和后端 在谈论接口测试之前&#xff0c;让我们先明确前端和后端这两个概念。 前端是我们在网页或移动应用程序中看到的页面&#xff0c;它由 HTML 和 CSS 编写而成…

写一个Django 的Demo

AIGC&#xff08;Artificial Intelligence Guided Control&#xff09;是一种基于人工智能技术的控制系统&#xff0c;其设计模式主要包括以下几个方面&#xff1a; 数据采集和处理&#xff1a;这一步骤主要是通过传感器等设备对物理参数进行采集&#xff0c;通过数据处理的方式…

【Python机器学习】零基础掌握Lasso变量选择回归器

如何优化房价预测模型,让它更加准确? 在生活中,房价预测一直是一个热门但复杂的问题。传统的线性回归模型虽然简单,但在处理高维数据时可能会遇到问题。例如,预测房价时,通常会考虑多个因素:面积、房间数、地理位置等。 假设有一组房屋数据,每条数据包含房屋的面积、…

五分钟理解Java跨平台原理(适合小白)

JVM通俗的理解 Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机&#xff0c;即JVM&#xff08;Java Virtual Machine&#xff09;是实现这一特点的关键。JVM是一种用于计算设备的规范&#xff0c;它是一个虚构出来的计算机&#xff0c;是通过在实际的计算机…

大厂面试题-什么是JVM

JVM全称是Java虚拟机&#xff0c;在聊什么是JVM之前&#xff0c;我们不妨看⼀下这张图。 从这张图中可以看出JVM所处的位置&#xff0c;同时也能看出它两个作用&#xff1a; 1、运⾏并管理Java源码⽂件所⽣成的Class⽂件&#xff0c; 2、在不同的操作系统上安装不同的JVM&#…

thinkphp 读取存放excel表格并进行数据填充

先读取存放在服务器项目中的原始excel表格 //原文件路径$filePath public_path() . "checklist.xlsx";$file IOFactory::load($filePath);$sheet $file->getActiveSheet();向表格中填充数据 $sheet->setCellValueByColumnAndRow(12, 3, date(Y年m月d日,strt…