如何抑制特定的Lint警告来处理已弃用的Android函数?

30

我使用版本切换来支持较旧的Android版本。

int sdk = Build.VERSION.SDK_INT;
if (sdk < Build.VERSION_CODES.HONEYCOMB) {
    ColorDrawable colorDrawable = new ColorDrawable(shapeColor);
    //noinspection deprecation
    viewHolder.shape.setBackgroundDrawable(colorDrawable);
} else {
    viewHolder.shape.setColor(shapeColor);
}

使用Gradle从命令行构建项目时,Lint会输出以下警告:

app/src/main/java/com/example/MyApp/CustomListAdapter.java:92: warning: 
[deprecation] setBackgroundDrawable(Drawable) in View has been deprecated
            viewHolder.shape.setBackgroundDrawable(colorDrawable);
                            ^

我能否注释掉导致警告的特定行或方法(因为我是故意这么做的)?我不想禁用所有警告。

我能否注释掉导致警告的特定行或方法(因为我是故意这么做的)?我不想禁用所有警告。


3
"//noinspection" 似乎是 IntelliJ 忽略警告的一种方式(Android Studio 基于 IntelliJ)。看起来 Android SDK 中有一个不一致之处 - 当您按 alt-enter 键时,IDE 提供使用此 //noinspection 语法,但构建系统会忽略它。我已提交了 https://code.google.com/p/android/issues/detail?id=73475。 - aleb
3
@aleb的错误报告被标记为“按预期运行”,并表示//noinspection应该是特定于IDE的,不应影响命令行操作,例如gradle构建。然而,文档没有做出这种区分,因此我提交了一个文档问题:https://code.google.com/p/android/issues/detail?id=204142&thanks=204142&ts=1458158680 - LarsH
@LarsH你具体建议使用什么?我尝试将@SuppressLint(“deprecation”)添加到方法中 - 但Gradle仍会报告警告。 - JJD
@JJD:抱歉,我不知道。我觉得应该可以工作。你尝试过user1的建议@SuppressWarnings("deprecation")了吗? - LarsH
@LarsH Gradle仍然输出带有java.lang.SuppressWarnings的警告。 - JJD
显示剩余7条评论
8个回答

18

大小写敏感,可以在行内或整个类中使用以下内容:

@Suppress("DEPRECATION")

这是Kotlin编写的。


2
在Java中大小写也很重要!在Java中,您需要使用小写来表示过时关键字@SuppressWarnings("deprecation") - Bruno Bieri
谢谢!我在寻找 Kotlin 的答案,这个有效。 - SpencerLS

13
我注意到@SuppressLint("deprecated")内联注释不再被捕获,而@SuppressWarnings("deprecation")是可以被捕获的。
一个人可以通过模块级别的build.gradle文件中的lintOptions禁用Gradle linter的Deprecation检查,而没有机会像那样定义单独的文件:
android {
    lintOptions {
        disable 'Deprecation'
    }
}

或者可以使用LintOptions:lintConfig分配一个非常详细的lint.xml配置文件(当设置showAll true时,它仍然会显示警告 - 无论提供的XML配置如何):

android {
    lintOptions {
        lintConfig file("lint.xml")
        showAll false
    }
}

用户可以通过添加文件路径来添加单个文件:

<?xml version="1.0" encoding="UTF-8"?>
<lint>
    <issue id="Deprecation" severity="Error">
        <ignore path="app/src/main/java/com/example/MyApp/CustomListAdapter.java" />
    </issue>
</lint>

com.android.builder.model.LintOptions的源代码可能会解释实际发生的情况(并确认了我写的内容大约50%的准确性)。

为了消除Android Studio中的内联警告...那个linter似乎是另一个linter——而这些注释不会影响Gradle构建的linter(可能需要将其与上述方法之一结合使用,以忽略已知的弃用类和方法):

//noinspection deprecation

更新 Android Studio 2.3 版本说明提到了一个新功能:

Lint Baseline: 在 Android Studio 2.3 中,您可以将未解决的 lint 警告设置为项目中的基准。从那时起,Lint 将仅报告新问题。如果您的应用程序中有许多遗留的 lint 问题,但只想专注于解决新问题,这会很有帮助。了解有关 Lint 基线和此版本中添加的新 Lint 检查和注释的更多信息。

此处 解释了如何创建 Lint 警告的 baseline - 将检测到的警告记录到 XML 文件中,然后将其静音(这比行内分布在各个地方的代码注释要好得多); 我认为,选项 lintConfigbaseline 可以组合使用(取决于要求)。

android {
    lintOptions {
        baseline file("lint-baseline.xml")
    }
}

1
不想禁用所有警告。 - JJD
@JJD 现在解释得更好了;基本上,一个人必须配置两个 linters(Android Studio 的 linter 和 Gradle 的 linter),以便消除所有不感兴趣的警告。其中 Android Studio 的 linter 是实时检查,而 Gradle 的 linter 是在构建时检查。 - Martin Zeitler
当我将您的lint.xml(带有我的类路径)放置在项目的根文件夹中时,Gradle仍会通知我在命令行执行构建时该类“使用或覆盖了已弃用的API”。此外,排除整个类有点过头了,因为我只想为单个行或函数静音忽略它的弃用。 - JJD
只能想象,lint.xmlbuild.gradle 中的 lintOptions 没有被引用...因此可能不会被代码检查工具遵守。 - Martin Zeitler
@JDD 请查看更新后的答案;还有https://www.jetbrains.com/help/idea/2016.1/specify-inspection-scope-dialog.html 网页似乎与实时代码检查相关。 - Martin Zeitler
谢谢更新,我也看到了公告。看起来非常有趣。我忘了提到你可以自己编译这个项目。它是开源的。你只需要暂时禁用这些编译器参数,就可以在使用Gradle编译时在shell中看到通知。 - JJD

7

有一些新东西:不确定Android Studio是否适用,但是你可以使用以下方法从此行中移除警告:

//noinspection deprecation

这会消除下一行的警告。例如:

//noinspection deprecation
e.setBackgroundDrawable(editTextDrawable);

它不会显示错误。然而,正如@JJD所说,这仍然会将警告输出到控制台。但至少你可以拥有一个漂亮的无错误代码,这对于例如Git等工具非常有用。并且,这可以防止@SupressWarnings的问题,即它忽略方法中的所有警告。因此,如果你有一些已经过时但你不知道的内容,@SupressWarnings会隐藏它,你就不会收到警告。这就是//noinspection的优势。


6

我遇到了类似的问题。首先,我收到了一个编译器警告:

:compileDebugJava
Note: /path/file.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.

您可以使用@SuppressWarnings("deprecation")来抑制它,或者忽略它,因为这只是一个警告,并不会导致构建失败。 另外,我还收到了 lint 错误(详见build/lint-results.html):
Call requires API level 13 (current min is 9)

这可以通过添加@SuppressLint("NewApi")来取消。或者,您可以使用@TargetApi(13)提示该方法/类可能使用取决于API版本13的方法,而不是您设置为minSdkVersion(例如9)的方法。
注释只能在类或函数级别完成,而不能针对单行进行注释。另请注意,“deprecation”不应大写,虽然对于“NewApi”似乎并不重要。

谢谢,不将关键字“deprecation”大写的提示对我非常关键。 - Bruno Bieri

3
为了避免出现代码检查警告,我们应该将函数拆分成两个部分,一部分处理旧系统,另一部分处理新系统。旧系统可以安全地忽略警告。新系统应该被注释为仅适用于最新的API级别。以下是一个示例:
    @SuppressWarnings("deprecation")
    private static int getVersionCode_old(@NonNull Context appContext) {
        PackageInfo pInfo;
        try {
            pInfo = appContext.getPackageManager().getPackageInfo(appContext.getPackageName(), 0);
            return pInfo.versionCode;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.P)
    private static int getVersionCode_new(@NonNull Context appContext) {
        PackageInfo pInfo ;
        try {
            pInfo = appContext.getPackageManager().getPackageInfo(appContext.getPackageName(), 0);
            return (int) pInfo.getLongVersionCode();
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    public static int getVersionCodeUniversal(@NonNull Context appContext)
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            return getVersionCode_new(appContext);
        }
        else
        {
            return getVersionCode_old(appContext);
        }
    }

另一个避免 lint 警告的重要提示:如果您正在使用整个已弃用的类,则应删除该类的所有显式导入。然后,直接使用其完整路径访问该类,并仅在函数的旧版本中执行此操作。
最后,您应考虑开始使用 androidX,这是新的 Google 库,您将在其中找到许多可立即使用的通用函数。然后,您可以通过这种类型的小问题节省大量时间。例如,您可以删除上面示例的所有代码,只需使用此新的通用 androidX 函数即可:
    PackageInfo.getLongVersionCode()

2
你需要创建一个lint.xml文件来告诉lint忽略哪些内容。 http://tools.android.com/tips/lint/suppressing-lint-warnings 详见此链接了解更多细节。
你的文件可能会类似于这样。
<?xml version="1.0" encoding="UTF-8"?>
<lint>
    <!-- Disable the given check in this project -->
    <issue id="Deprecation">
        <ignore path="app/src/main/java/com/example/MyApp/CustomListAdapter.java" />
    </issue>
</lint>

处理源代码时,您应该使用类似以下的内容:
 @SuppressLint("Deprecation")

2
我不想禁用所有弃用警告。我更愿意在代码的特定行添加一个 Lint 注释。 - JJD
2
我按照文档中建议的方法尝试了 //noinspection AndroidLintDeprecation,但警告仍然出现。我不确定所谓的 id 是什么意思。 可以在此处[(https://android.googlesource.com/platform/tools/adt/idea/+/jb-mr2-dev/android/src/org/jetbrains/android/inspections/lint/SuppressLintIntentionAction.java)]中看到提取的 lintId,在第169行。如果我理解正确,@SuppressLint("Deprecation") 只能在方法级别上设置。 - JJD
2
将那个if语句拆分成一个带有抑制lint注解的单独方法不是最简单的解决方案吗? - bestdayever
1
你是指 //noinspection deprecation 吗?但是除此之外,Gradle 仍然会将警告输出到控制台。 - JJD
它对于这个项目(https://bitbucket.org/tbsprs/umweltzone)无效。工具几乎是最新的(正在进行中)。 - JJD
显示剩余5条评论

0

尝试从ViewCompat中找到一种方法来替换已弃用的方法。

在您的情况下,请使用ViewCompat.setBackground(View, Drawable)

有许多类名为XXXCompat的类可用于此类情况,例如ContextCompatActivityCompat等。


0

只需在函数上方使用@SuppressWarnings("deprecation")来仅抑制该函数的特定警告。

非常好用!

@Blackd 给出了更好的答案。你应该接受它!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接