Android 8(1),面试真题解析

Android 8.0 引入了快捷方式和微件的应用内固定功能。在您的应用中,您可以根据用户权限为支持的启动器创建固定的快捷方式和小部件。

如需了解详细信息,请参阅固定快捷方式和微件预览功能指南。

最大屏幕纵横比

以 Android 7.1(API 级别 25)或更低版本为目标平台的应用默认的最大屏幕纵横比为 1.86。针对 Android 8.0 或更高版本的应用没有默认的最大纵横比。如果您的应用需要设置最大纵横比,请使用定义您的操作组件的清单文件中的 maxAspectRatio 属性。

多显示器支持

从 Android 8.0 开始,此平台为多显示器提供增强的支持。如果 Activity 支持多窗口模式,并且在具有多显示器的设备上运行,则用户可以将 Activity 从一个显示器移动到另一个显示器。当应用启动 Activity 时,此应用可指定 Activity 应在哪个显示器上运行。

注:如果 Activity 支持多窗口模式,则 Android 8.0 将为该 Activity 自动启用多显示器支持。您应测试您的应用, 确保它在多显示器环境下可正常运行。

每次只有一个 Activity 可以处于继续状态,即使此应用具有多个显示器。具有焦点的 Activity 将处于继续状态,所有其他可见的 Activity 均暂停,但不会停止。如需了解有关当多个 Activity 可见时活动生命周期的详细信息,请参阅多窗口生命周期。

当用户将 Activity 从一个显示器移动到另一个显示器时,系统将调整 Activity 大小,并根据需要发起运行时变更。您的 Activity 可以自行处理配置变更,或允许系统销毁包含该 Activity 的进程,并以新的尺寸重新创建它。如需了解详细信息,请参阅处理配置变更。

ActivityOptions 提供两个新函数以支持多个显示器:

  • setLaunchDisplayId() 指定 Activity 在启动后应显示在哪个显示器上。
  • getLaunchDisplayId() 返回操作组件的当前启动显示器。

对 adb shell 进行了扩展,以支持多个显示器。shell start 命令现在可用于启动操作组件,并指定操作组件的目标显示器:

adb shell start <activity_name> --display <display_id>

统一的布局外边距和内边距

Android 8.0 让您可以更轻松地指定 View 元素的对边使用相同外边距和内边距的情形。具体来说,您现在可以在布局 XML 文件中使用以下属性:

  • layout_marginVertical,同时定义 layout_marginTop 和 layout_marginBottom。
  • layout_marginHorizontal,同时定义 layout_marginLeft 和 layout_marginRight。
  • paddingVertical,同时定义 paddingTop 和 paddingBottom。
  • paddingHorizontal,同时定义 paddingLeft 和 paddingRight。

注:如果您自定义应用逻辑以支持不同语言和文化(包括文本方向), 请记住,这些属性不会影响 layout_marginStart、layout_marginEnd、paddingStart 或 paddingEnd 的值。您可以自行设置这些值和新的垂直与水平布局属性 来创建取决于文本方向的布局行为。

指针捕获

某些应用(例如游戏、远程桌面和虚拟化客户端)将大大受益于鼠标指针控制。指针捕获是 Android 8.0 中的一项新功能,可以通过将所有鼠标事件传递到您的应用中焦点视图的方式提供此类控制。

从 Android 8.0 开始,您的应用中的 View 可以请求指针捕获并定义一个侦听器来处理捕获的指针事件。鼠标指针在此模式下将隐藏。如果不再需要鼠标信息,该视图可以释放指针捕获。系统也可以在视图丢失焦点时(例如,当用户打开另一个应用时)释放指针捕获。

应用类别

在适当的情况下,Android 8.0 允许每个应用声明其所属的类别。这些类别用于将应用呈现给用户的用途或功能类似的应用归类在一起,例如按流量消耗、电池消耗和存储消耗将应用归类。您可以在

Android TV 启动器

Android 8.0 添加了一种以内容为中心的全新 Android TV 主屏幕体验,支持 Android TV 模拟器和 Nexus Player Android 8.0 设备映像。新的主屏幕在对应于频道的行中组织视频内容,这些频道在系统上通过应用填充各个节目。应用可以发布多个频道,用户可以配置他们希望在主屏幕上看到哪些频道。Android TV 也包含一个 Watch Next 行,此行根据用户的观看习惯从应用填充节目。应用也可以提供视频预览,这些预览会在用户聚焦到节目时自动播放。用于填充频道和节目的 API 属于 TvProvider API,这些 API 以 Android 支持库模块的形式随 Android 8.0 分发。

AnimatorSet

从 Android 8.0 开始,AnimatorSet API 现在支持寻道和倒播功能。寻道功能允许您将动画的位置设置为指定的时间点处。如果您的应用包含可撤消的操作的动画,倒播功能会很有用。现在,您不必定义两组独立的动画,而只需反向播放同一组动画。

输入和导航

键盘导航键区

如果您的应用中,某个操作组件使用一种复杂的视图层次结构(如图 2 所示),可考虑将多组界面元素组成一个键区,简化键盘导航这些元素的操作。用户可以在 Chromebook 设备上按 Meta+Tab 或 Search+Tab,在不同键区之间导航。键区的一些范例包括:侧面板、导航栏、主内容区域和可能包含多个子元素的元素。

以一个包含五个导航键区的操作组件为例,用户可以使用键盘导航键区快捷键进行导航。键区按以下布局显示:顶部面板、左侧面板、主内容区域、底部面板和浮动操作按钮。

要将一个 View 或 ViewGroup 元素设置为一个键区,请在元素的布局 XML 文件中将 android:keyboardNavigationCluster 属性设置为 true,或者将 true 传递至应用界面逻辑中的 setKeyboardNavigationCluster()。

注:键区不能嵌套,不过,非嵌套键区可以显示在层次结构的不同层级。 如果您尝试嵌套键区,框架仅会将最顶层的 ViewGroup 元素视为键区。

在具有触摸屏的设备中,您可以将某个键区指定的 ViewGroup 对象的 android:touchscreenBlocksFocus 元素设置为 true,仅允许从键区导航进入和离开此键区。如果您将此配置应用于某个键区,用户将无法使用 Tab 键或箭头键导航进入或离开此键区,而是必须按键区导航键盘组合键。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

视图默认焦点

在 Android 8.0 中,您可以指定在(重新)创建的操作组件继续运行并且用户按下键盘导航键(例如 Tab 键)之后应接收焦点的 View。要应用“设为默认焦点”设置,请在包含界面元素的布局 XML 文件中将 View 元素的 android:focusedByDefault 属性设置为 true,或者将 true 传递至应用界面逻辑中的 setFocusedByDefault()。

系统

新的 StrictMode 检测程序

Android 8.0 添加了三个新的 StrictMode 检测程序,帮助识别应用可能出现的错误:

  • detectUnbufferedIo() 将检测您的应用何时读取或写入未缓冲的数据,这可能极大影响性能。
  • detectContentUriWithoutPermission() 将检测您的应用在其外部启动 Activity 时何时意外忘记向其他应用授予权限。
  • detectUntaggedSockets() 将检测您的应用何时使用网络流量,而不使用 setThreadStatsTag(int) 将流量标记用于调试目的。
缓存数据

Android 8.0 优化了缓存数据的导航和行为。现在,每个应用均获得一定的磁盘空间配额,用于存储 getCacheQuotaBytes(UUID) 返回的缓存数据。

当系统需要释放磁盘空间时,将开始从超过配额最多的应用中删除缓存文件。因此,如果将您的缓存数据量始终保持低于配额的水平,则在必须清除系统中的某些文件时,您的缓存文件将能坚持到最后。系统在决定删除您的应用中的哪些缓存文件时,将首先考虑删除最旧的文件(由修改时间确定)。

您还可以针对每个目录启用两种新行为,以控制系统如何释放缓存数据:

  • StorageManager.setCacheBehaviorAtomic() 可用于指示某个目录及其所有内容应作为一个不可分割的整体进行删除。
  • setCacheBehaviorTombstone(File, boolean) 可用于指示不应删除某个目录内的文件,而应将它们截断到 0 字节长度,使空文件保持完好。

最后,在需要为大文件分配磁盘空间时,可考虑使用新的 allocateBytes(FileDescriptor, long) API,它将自动清除属于其他应用的缓存文件(根据需要),以满足您的请求。在确定设备是否有足够的磁盘空间保存您的新数据时,请调用 getAllocatableBytes(UUID) 而不要使用 getUsableSpace(),因为前者会考虑系统要为您清除的任何缓存数据。

内容提供程序分页

我们已更新内容提供程序以支持加载大型数据集,每次加载一页。例如,一个具有大量图像的照片应用可查询要在页面中显示的数据的子集。内容提供程序返回的每个结果页面由一个 Cursor 对象表示。客户端和提供程序必须实现分页才能利用此功能。

内容刷新请求

现在,ContentProvider 和 ContentResolver 类均包含 refresh() 函数,这样,客户端可以更轻松地知道所请求的信息是否为最新信息。

您可以扩展 ContentProvider 以添加自定义的内容刷新逻辑。请务必重写 refresh() 函数,以返回 true,告知提供程序的客户端您已尝试自行刷新数据。

您的客户端应用可通过调用另一个函数(又称 refresh()),显式请求已刷新的内容。在调用此函数时,传入待刷新数据的 URI。

注:由于您可能通过网络不断请求数据, 您应仅在有明显迹象表明内容确已过时时才从客户端调用 refresh()。 执行此类内容刷新最常见的原因是响应滑动刷新手势, 该手势显式请求当前界面显示最新内容。

JobScheduler 改进

Android 8.0 引入了对 JobScheduler 的多项改进。由于您通常可以使用计划作业替代现在受限的后台服务或隐式广播接收器,这些改进可以让您的应用更轻松地符合新的后台执行限制。

JobScheduler 的更新包括:

  • 您现在可以将工作队列与计划作业关联。要将一个工作项添加到作业的队列中,请调用 JobScheduler.enqueue()。当作业运行时,它可以将待定工作从队列中剥离并进行处理。这种功能可以处理之前需要启动后台服务(尤其是实现 IntentService 的服务)的许多用例。
  • 您现在可以通过调用 JobInfo.Builder.setClipData() 的方式将 ClipData 与作业关联。利用此选项,您可以将 URI 权限授予与作业关联,类似于这些权限传递到 Context.startService() 的方式。您也可以将 URI 权限授予用于工作队列上的 intent。
  • 计划作业现在支持多个新的约束条件:JobInfo.isRequireStorageNotLow()
    如果设备的可用存储空间非常低,作业将不会运行。
    JobInfo.isRequireBatteryNotLow()
    如果电池电量等于或低于临界阈值,作业将不会运行;临界阈值是指设备显示 Low battery warning 系统对话框的电量。
    NETWORK_TYPE_METERED
    作业需要一个按流量计费的网络连接,比如大多数移动数据网络数据套餐。

自定义数据存储

Android 8.0 允许您为首选项提供自定义数据存储,如果您的应用将首选项存储在云或本地数据库中,或者如果首选项特定于某个设备,此功能会非常有用。如需了解有关实现数据存储的详细信息,请参阅自定义数据存储。

findViewById() 签名变更

现在,findViewById() 函数的全部实例均返回

  • 例如,如果 someMethod(View) 和 someMethod(TextView) 均接受调用 findViewById() 的结果,这可能导致现有代码的返回类型不确定。
  • 在使用 Java 8 源语言时,这需要在返回类型不受限制时(例如,assertNotNull(findViewById(…)).someViewMethod()))显式转换为 View。
  • 重写非最终的 findViewById() 函数(例如,Activity.findViewById())将需要更新其返回类型。

媒体增强功能

VolumeShaper

有一个新的 VolumeShaper 类。您可以用它来执行简短的自动音量转换,例如淡入、淡出和交叉淡入淡出。

音频焦点增强功能

音频应用通过请求和舍弃音频焦点的方式在设备上共享音频输出。应用通过启动或停止播放或者闪避音量的方式处理处于聚焦状态的变更。有一个新的 AudioFocusRequest 类。对于此类,应用在处理音频焦点变化时会使用新功能:自动闪避和延迟聚焦。

媒体指标

新的 getMetrics() 函数将返回一个包含配置和性能信息的 PersistableBundle 对象,用一个包含属性和值的地图表示。为以下媒体类定义 getMetrics() 函数:

  • MediaPlayer.getMetrics()
  • MediaRecorder.getMetrics()
  • MediaCodec.getMetrics()
  • MediaExtractor.getMetrics()

为每个实例单独收集指标,并持续到实例的生命周期结束为止。如果没有可用的指标,则此函数将返回 null。返回的实际指标取决于类。

MediaPlayer

Android 8.0 为 MediaPlayer 类添加了多种新函数。这些函数可以从多个方面增强您的应用处理媒体播放的能力:

  • 在搜索帧时进行精细控制。
  • 播放受数字版权管理保护的材料的功能。

MediaPlayer 现在支持采样级加密。

音频录制器
  • 音频录制器现在支持对流式传输有用的 MPEG2_TS 格式:mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS);
  • MediaMuxer 现在可以处理任意数量的音频和视频流,而不再仅限于一个音频曲目和/或一个视频曲目。使用 addTrack() 可混录所需的任意数量的曲目。
  • MediaMuxer 还可以添加一个或多个包含用户定义的每帧信息的元数据曲目。元数据的格式由您的应用定义。仅对 MP4 容器支持元数据曲目。

元数据可以用于离线处理。例如,传感器的陀螺仪信号可以用于执行视频稳定操作。

在添加元数据曲目时,曲目的 MIME 格式必须以前缀“application/”开头。除了数据不是来源于 MediaCodec 以外,写入元数据的操作与写入视频/音频数据相同。相反,应用将包含相关时间戳的 ByteBuffer 传递给 writeSampleData() 函数。时间戳必须和视频及音频曲目处于相同的时基。

生成的 MP4 文件使用 ISOBMFF 的 12.3.3.2 部分定义的 TextMetaDataSampleEntry,指示元数据的 MIME 格式。在使用 MediaExtractor 提取包含元数据曲目的文件时,元数据的 MIME 格式将提取到 MediaFormat 中。

音频播放控制

Android 8.0 允许您查询和请求设备产生声音的方式。对音频播放的以下控制将让您的服务更轻松地仅在有利的设备条件下产生声音。

Google 智能助理的新音频使用类型

AudioAttributes 类包含一种新的声音类型,即 USAGE_ASSISTANT,对应于 Google 智能助理在设备上的回答。

设备音频播放的变更

如果您希望自己的服务仅在特定的设备音频配置处于活动状态时开始产生声音,您可以使用 AudioManager 类注册一个 AudioManager.AudioPlaybackCallback 实例,后者的onPlaybackConfigChanged() 函数可以帮助您确定当前活动的音频属性集。

显式请求音频焦点

您的服务可以使用 requestAudioFocus() 函数提交一个更精细的设备级音频焦点接收请求。传入一个 AudioFocusRequest 对象,您可以使用 AudioFocusRequest.Builder 创建这个对象。在这个构建类中,您可以指定以下选项:

  • 您希望获得的焦点类型,例如 AUDIOFOCUS_GAIN_TRANSIENT 或 AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK。
  • 当另一个音频服务获得设备焦点时,您的服务应以更安静的方式继续,还是完全暂停。
  • 您的服务能否等待获得焦点,直至设备就绪。

注:构建您的 AudioFocusRequest 实例时,如果您通过调用 setAcceptsDelayedFocusGain() 指示您的服务可以等待产生声音,您也必须调用 setOnAudioFocusChangeListener(),以便您的服务了解它何时可以开始产生声音。

增强的媒体文件访问功能

存储访问框架 (SAF) 允许应用显示自定义 DocumentsProvider,后者可以为其他应用提供访问数据源中的文件的权限。事实上,文档提供程序甚至可以提供驻留在网络存储区或使用媒体传输协议 (MTP) 等协议的文件的访问权限。

但是,访问远程数据源中的大媒体文件面临一些挑战:

  • 媒体播放器需要以寻址方式访问来自文档提供程序的文件。当大媒体文件驻留在远程数据源上时,文档提供程序必须事先提取所有数据,并创建快照文件描述符。媒体播放器无法播放没有文件描述符的文件,因此在文档提供程序完成文件下载前,无法开始播放。
  • 照片应用等媒体集合管理器必须通过作用域文件夹遍历一系列访问 URI 才能访问存储在外部 SD 卡上的媒体。这种访问模式会让媒体上的批量操作(例如移动、复制和删除)变得非常缓慢。
  • 媒体集合管理器无法根据文档的 URI 确定其位置。这就让这些类型的应用难以允许用户选择媒体文件的保存位置。

Android 8.0 通过改进存储访问框架解决了各个挑战。

自定义文档提供程序

从 Android 8.0 开始,存储访问框架允许自定义文档提供程序为驻留在远程数据源中的文件创建可寻址的文件描述符。SAF 可打开文件,获取原生可寻址的文件描述符。然后 SAF 向文档提供程序提交离散字节请求。此功能使文档提供程序可以返回媒体播放器应用请求的准确字节范围,而不必事先缓存整个文件。

要使用此功能,您需要调用新的 StorageManager.openProxyFileDescriptor() 函数。openProxyFileDescriptor() 函数可接受 ProxyFileDescriptorCallback 对象作为回调。任何时候,当客户端应用对文档提供程序返回的文件描述符执行文件操作时,SAF 都会调用回调。

直接文档访问

从 Android 8.0 开始,您可以使用 getDocumentUri() 函数获得与给定 mediaUri 引用相同文档的 URI。不过,由于返回的 URI 由 DocumentsProvider 提供支持,媒体集合管理器可以直接访问文档,不用遍历作用域目录树。因此,媒体管理器能够以明显加快的速度对文档执行文件操作。

注意:getDocumentUri() 函数仅可以定位媒体文件;无法授予应用访问这些文件的权限。要详细了解如何获取媒体文件的访问权限,请参阅参考文档。

文档路径

在 Android 8.0 中使用存储访问框架时,您可以根据文档的 ID,使用 findDocumentPath() 函数(存在于 DocumentsContract 和 DocumentsProvider 类中)从文件系统的根目录中确定路径。该函数将在 DocumentsContract.Path 对象中返回此路径。如果文件系统对相同文档有多个定义的路径,该函数将返回访问具有给定 ID 的文档时最常使用的路径。

此功能在下列情况下特别有用:

  • 您的应用使用可以显示特定文档位置的“另存为”对话框。
  • 您的应用在搜索结果视图中显示文件夹并且如果用户选择某个文件夹,应用必须加载此特定文件夹内的子文档。

注:如果您的应用仅具有路径中某些文档的访问权限,那么 findDocumentPath() 的返回值将仅包含您的应用可以访问的文件夹和文档。

连接

WLAN 感知

Android 8.0 新增了对 WLAN 感知的支持,此技术基于周边感知联网 (NAN) 规范。在具有相应 WLAN 感知硬件的设备上,应用和附近设备可以通过 WLAN 进行搜索和通信,无需依赖互联网接入点。我们正在与硬件合作伙伴合作,以尽快将 WLAN 感知技术应用于设备。要了解有关如何将 WLAN 感知集成到您的应用中的信息,请参阅 WLAN 感知。

蓝牙

Android 8.0 通过增加以下功能,增强了平台对蓝牙的支持:

  • 支持 AVRCP 1.4 标准,该标准支持音乐库浏览。
  • 支持蓝牙低功耗 (BLE) 5.0 标准。
  • 将 Sony LDAC 编解码器集成到蓝牙堆叠中。
配套设备配对

在尝试通过蓝牙、BLE 和 WLAN 与配套设备配对时,Android 8.0 提供的 API 允许您自定义配对请求对话框。如需了解详细信息,请参阅配套设备配对。

如需了解有关在 Android 上使用蓝牙的详细信息,请参阅蓝牙指南。有关对蓝牙所作的特定于 Android 8.0 的变更,请参阅 Android 8.0 行为变更页面的蓝牙部分。

共享

智能共享

Android 8.0 了解用户的个性化分享首选项,在通过哪些应用分享各个类型的内容方面,也有着更好的把握。例如,如果用户为一张收据拍照,Android 8.0 可以建议费用跟踪应用;如果用户自拍,一款社交媒体应用可以更好地处理图像。Android 8.0 可以根据用户的个性化首选项自动学习所有这些模式。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

最后笔者收集整理了一份Flutter高级入门进阶资料PDF

以下是资料目录和内容部分截图



里面包括详细的知识点讲解分析,带你一个星期入门Flutter。还有130个进阶学习项目实战视频教程,让你秒变大前端。学不会来打我!

id)**
[外链图片转存中…(img-ns5IDeWu-1711131776378)]

最后笔者收集整理了一份Flutter高级入门进阶资料PDF

以下是资料目录和内容部分截图

[外链图片转存中…(img-JI74iwaU-1711131776379)]
[外链图片转存中…(img-6DHu3TAa-1711131776379)]
里面包括详细的知识点讲解分析,带你一个星期入门Flutter。还有130个进阶学习项目实战视频教程,让你秒变大前端。学不会来打我!
[外链图片转存中…(img-A4wv2PQ6-1711131776379)]
以上资料皆无偿分享,领取方式:点击我的GitHub即可免费获取

  • 24
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值