普通文本  |  188行  |  7.78 KB

# API Lint

Metalava can optionally run warn about various API problems based on the Android
API Council's guidelines, described in go/android-api-guidelines.

These rules are not always exact. For example, you should avoid using acronyms
in names; e.g. a method should be named handleUri, not handleURI. But what about
getZOrder?  This is probably better than getZorder, but metalava can't tell
without consulting a dictionary.

Therefore, there are cases where you want to say "ok, that's good advice in
general, but wrong here". In order to avoid having this warningshow up again
and again, there are two ways to mark an issue such that it is no longer
flagged.

(Note that metalava will not report issues on classes, methods and fields that
are deprecated since these are presumably already known to be bad and are already
discouraged.)

## Suppressing with @Suppress

Next to an error message, metalava will include the issue id. For example,
here's a sample error message:

    src/android/pkg/MyStringImpl.java:3: error: Don't expose your implementation details: MyStringImpl ends with Impl [EndsWithImpl]

Here the id is "EndsWithImpl". You can suppress this with the @SuppressLint
annotation:

    ...
    import android.annotation.SuppressLint;
    ...

    @SuppressLint("EndsWithImpl")
    public class MyStringImpl {
        ...

## Suppressing with baselines

Metalava also has support for "baselines", which are files which record all the
current warnings and errors in the codebase. When metalava runs, it looks up the
baseline to see if a given issue is already listed in the baseline, and if so,
it is silently ignored.

You can pass a flag to metalava ("--update-baseline") to tell it to update the
baseline files with any new errors it comes across instead of reporting
them. With soong, if you specify the baseline explicitly, like this:

    --- a/Android.bp
    +++ b/Android.bp
    @@ -1678,6 +1678,7 @@ droidstubs {
         },
         api_lint: true,
    ==>  baseline_filename: "api/baseline.txt", <==
         jdiff_enabled: true,
     }

then the build system will automatically supply `--update-baseline` on your
behalf to a generated file in the out/ folder, and if there's a failure metalava
will tell you where to find the updated baseline which you can then copy into
place:

    ...
    93 new API lint issues were found. See tools/metalava/API-LINT.md for how to handle these.
    ************************************************************
    Your API changes are triggering API Lint warnings or errors.
    To make these errors go away, you have two choices:

    1. You can suppress the errors with @SuppressLint("<id>")
    2. You can update the baseline by executing the following
       command:
           cp \
           out/soong/.intermediates/frameworks/base/system-api-stubs-docs/android_common/api/system-baseline.txt \
           frameworks/base/api/system-baseline.txt
       To submit the revised baseline.txt to the main Android
       repository, you will need approval.
    ************************************************************



Then re-run the build and you should now see diffs to the baseline file; git
diff to make sure you're really only marking the issues you intended to include.

    $ git status
    ...
    Untracked files:
      (use "git add <file>..." to include in what will be committed)

          baseline.txt

## Copying File Manually

In the near future the build system will not allow source files to be modified
by the build. At that point you'll need to manually copy in the file instead.
During the build, before failing, metalava will emit a message like this:

    ...
    metalava wrote updated baseline to out/something/baseline.txt
    ...

At that point you can copy the file to where you need:

```sh
$ cp out/something/baseline.txt frameworks/base/api/baseline.txt
```

## Existing Issues

You can view the exact set of existing issues (current APIs that get flagged by
API lint) by inspecting the baseline files in the source tree, but to get a
sense of the types of issues that are more likely to have a false positive,
here's the existing distribution as of early 2019:

    Count Issue Id                       Rule Severity
    --------------------------------------------------

      932 ProtectedMember                M7   error
      321 OnNameExpected                      warning
      288 ArrayReturn                         warning
      269 ActionValue                    C4   error
      266 NoByteOrShort                  FW12 warning
      221 ExecutorRegistration           L1   warning
      211 AllUpper                       C2   error
      206 GetterSetterNames              M6   error
      185 BannedThrow                         error
      172 SamShouldBeLast                     warning
      159 NoClone                             error
      159 ParcelNotFinal                 FW8  error
      119 NotCloseable                        warning
      105 ListenerLast                   M3   warning
       81 ConcreteCollection             CL2  error
       78 StaticUtils                         error
       76 IntentName                     C3   error
       74 VisiblySynchronized            M5   error
       72 GenericException               S1   error
       65 KotlinOperator                      warning
       57 AcronymName                    S1   warning
       55 ParcelCreator                  FW3  error
       54 ParcelConstructor              FW3  error
       53 UseIcu                              warning
       48 Enum                           F5   error
       41 RethrowRemoteException         FW9  error
       37 AutoBoxing                     M11  error
       35 StreamFiles                    M10  warning
       28 IntentBuilderName              FW1  warning
       27 ServiceName                    C4   error
       26 ListenerInterface              L1   error
       25 ContextFirst                   M3   error
       25 InterfaceConstant              C4   error
       24 CallbackInterface              CL3  error
       24 RegistrationName               L3   error
       23 IllegalStateException          S1   warning
       22 EqualsAndHashCode              M8   error
       22 PackageLayering                FW6  warning
       18 MinMaxConstant                 C8   warning
       18 SingletonConstructor                error
       17 MethodNameUnits                     error
       15 MissingBuild                        warning
       15 UserHandleName                      warning
       14 UserHandle                          warning
       13 ResourceFieldName                   error
       12 ManagerLookup                       error
       11 ManagerConstructor                  error
        9 CallbackMethodName             L1   error
        9 ParcelableList                      warning
        8 CallbackName                   L1   warning
        7 HeavyBitSet                         error
        7 ResourceValueFieldName         C7   error
        6 CompileTimeConstant                 error
        6 SetterReturnsThis              M4   warning
        4 EndsWithImpl                        error
        4 TopLevelBuilder                     warning
        4 UseParcelFileDescriptor        FW11 error
        3 MentionsGoogle                      error
        3 StartWithLower                 S1   error
        2 AbstractInner                       warning
        2 BuilderSetStyle                     warning
        2 OverlappingConstants           C1   warning
        2 PairedRegistration             L2   error
        2 SingularCallback               L1   error
        2 StartWithUpper                 S1   error
        1 ContextNameSuffix              C4   error
        1 KotlinKeyword                       error
    --------------------------------------------------
     4902

(This is generated when metalava is invoked with both --verbose and --update-baseline.)