Android中的默认接口方法:Nougat错误及其解决方案(Kotlin)

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:“隐形”错误,破坏构建

\n\n

您正在用Kotlin编写应用程序,一切进展顺利,但突然——砰!——Android Studio将某一行标红,构建日志中出现一条可怕的消息:

\n\n
Default interface methods are only supported starting with Android 7.0 (Nougat)
\n\n

熟悉的情况吗?如果您是Android开发新手,这个错误可能看起来像一个真正的谜题。您只是使用了一个带有默认方法的接口——能出什么问题呢?

\n\n

实际上,问题在于您应用程序的minSdkVersion与Kotlin语言(它在内部使用了Java 8的特性)的功能不兼容。

\n\n

在本文中,我们将分析为什么会出现这个错误,如何修复它,以及如何在保持对旧设备支持的同时编写现代代码。开始吧!

\n\n

什么是“default interface method”,它为什么会出现?

\n\n

让我们从基础开始。在旧版本的Java(8之前)中,接口只能包含方法声明——没有实现。但随着Java 8的到来,可以在接口中添加带有方法体的方法(即所谓的默认方法)。

\n\n

Kotlin作为一种现代语言,完全支持这一概念。例如:

\n\n
interface Logger {\n    fun log(message: String)\n    fun logWithTimestamp(message: String) {\n        log("${System.currentTimeMillis()}: $message")\n    }\n}
\n\n

这里的logWithTimestamp就是一个默认接口方法。如果一个类实现了Logger,它可以不重写这个方法,而是使用“默认”实现。很方便,对吧?

\n\n

问题在于,在字节码层面,Android需要操作系统的支持才能执行这些方法。而这种支持只在Android 7.0 (Nougat, API 24)中才出现。

\n\n

为什么Android Studio中会出现这个错误?

\n\n

当您将minSdkVersion设置为低于24(例如21或23)时,Android编译器会看到您的应用程序可能运行在Android 6.0或5.0的设备上。而在这些版本上,接口默认方法在虚拟机(Dalvik/ART)层面不受支持。

\n\n

正是因此,编译器会报错:

\n\n
Default interface methods are only supported starting with Android 7.0 (Nougat)
\n\n

它字面意思是:“我无法编译这段代码,因为你的应用程序可能会在无法执行这些方法的设备上运行。”

\n\n

典型的发生场景

\n\n

大多数情况下,这个错误出现在两种场景中:

\n\n
    \n
  • 使用Kotlin集合(例如listOf、mapOf)——它们有默认方法。
  • \n
  • 使用第三方库,这些库内部包含带有默认方法的接口。
  • \n
  • 使用Android Jetpack(例如LifecycleObserver或DefaultLifecycleObserver)。
  • \n
\n\n

即使您自己不编写带有默认方法的接口——如果某个依赖项使用了它们,错误仍然会出现。

\n\n

如何修复这个错误?3种经过验证的方法

\n\n

让我们来看看所有可能的解决方案——从最简单到更灵活的。

\n\n

方法1:将minSdkVersion提升到24

\n\n

这是最直接的解决方案。如果您的应用程序不必支持Android 7.0之前的设备,只需在build.gradle文件(模块级别)中更改minSdkVersion:

\n\n
android {\n    ...\n    defaultConfig {\n        minSdkVersion 24\n        targetSdkVersion 34\n        ...\n    }\n}
\n\n

优点:快速、干净

博客

书籍推荐