/ ANDROID, LINT

Android Lint - 프로젝트 내 문제를 미리 파악하자

Android Lint는 안드로이드 애플리케이션을 구성하는 코드(소스 코드, 리소스, 매니페스트 등)를 정적 분석하는 도구입니다.

여기에서 수행하는 검사를 통해, 작성한 코드 내에서 발생할 수 있는 잠재적인 문제(특정 버전에서 발생할 수 있는 문제 등) 및 성능에 지장을 줄 수 있는 문제를 미리 검출하여 코드 품질을 높을 수 있습니다.

검사하는 항목

Android Lint에서 검사하는 항목 중 대표적인 부분은 다음과 같습니다.

  • 사용하지 않는 리소스
  • 국제화(I18N; Internationalization) 지원시 이상 여부
  • 성능상 문제가 될 수 있는 부분
  • minSdkLevel, targetSdkLevel, compileSdkLevel에 따라 오류가 발생할 수 있는 부분

각 검사는 고유한 검사 ID가 부여되어 있으며, 일반적으로 많이 접하는 검사ID 및 검사 내용은 다음과 같습니다.

검사 ID 내용
CheckResult 메서드의 결과값을 사용하지 않은 경우
MissingTranslation 특정 언어에 대한 번역 텍스트 없음
NewApi 구 버전 OS에서 새 버전에서 추가된
RelativeOverlap RelativeLayout을 사용하는 경우, 언어에 따라 다른 구성요소의 영역을 침범할 가능성이 있음
UnusedResources 프로젝트에서 사용하지 않는 리소스

전체 검사 항목은 Android Tools 프로젝트 페이지를 통해 확인할 수 있습니다.

검출 단계

검사 후 검출된 항목은 중요도에 따라 다음 세 단계로 나뉩니다.

  • 정보 (Informational)
    • 중요도가 매우 낮거나 단순 참고용으로 볼 만한 항목입니다.
  • 경고 (Warning)
    • 예상치 못한 동작의 원인이 될 만한 항목입니다.
  • 오류 (Error)
    • 적절한 조치를 취하지 않으면 심각한 문제를 발생시킬 수 있는 항목입니다. 여기에 해당하는 항목이 하나라도 있을 경우 애플리케이션 바이너리 생성시(Export 메뉴를 사용하거나 Gradle 사용) 오류가 발생합니다.

검사 수행하기

Android Studio 및 Gradle을 사용하면 애플리케이션 빌드 시 검사를 같이 수행할 수 있습니다.

Android Studio

안드로이드 스튜디오 내 메뉴 > Analyze > Inspect Code… 를 통해 실행할 수 있습니다. 실행시 Android Lint 외 다른 검사도 함께 수행할 수 있습니다.

post

Inspect Code 메뉴 선택시 나오는 다이얼로그

Inspection profile에서 선택된 프로필 오른쪽의 ‘…’ 버튼을 누르면 ‘Inspections’ 창이 뜨면서 수행할 검사 종류를 선택할 수 있습니다.

수행할 검사를 선택할 수 있습니다.

검사 결과는 다음과 같이 하단 ‘Inspection’ 탭에 표시됩니다. 검사 항목 및 문제가 발생한 항목을 확인할 수 있습니다.

표시된 항목을 선택하면, 우측에 다음과 같이 상세한 내용 및 파일 정보가 표시됩니다.

Gradle

./gradlew lint 명령 (윈도의 경우 gradlew.bat lint)을 사용하여 검사를 수행합니다. Gradle wrapper를 사용하지 않는다면 gradle lint 명령을 사용하면 됩니다.

검사를 수행하면 다음과 같이 간단한 검사 결과가 표시됩니다.

$ ./gradlew lint
... (생략) ...
:sample:generateReleaseSources
:sample:processReleaseJavaRes UP-TO-DATE
:sample:compileReleaseJavaWithJavac
:sample:lint
Ran lint on variant debug: 4 issues found
Ran lint on variant release: 4 issues found
Wrote HTML report to file:/Users/kunny/git/android-SectionAdapter/sample/build/outputs/lint-results.html
Wrote XML report to /Users/kunny/git/android-SectionAdapter/sample/build/outputs/lint-results.xml

BUILD SUCCESSFUL

Total time: 17.543 secs

상세한 검사 결과는 각 모듈 경로 내 build/outputs/lint-results.html에서 확인할 수 있습니다. 검사 결과의 맨 처음 부분에는 다음과 같이 검사 결과에 대한 요약이 표시되고, 아래 부분에 각각에 해당하는 자세한 결과가 표시됩니다.

검사 결과 처리 방법 변경

검사 결과에서 문제가 있다고 판단한 항목일 지라도, 프로젝트 구성에 따라 정상이거나 의도적으로 작성된 부분이 있을 수 있습니다. 이러한 경우 검사 설정을 변경하여 문제가 되는 부분을 별도로 수정할 수 있습니다.

검사 설정은 소스 코드, 빌드 스크립트, 별도 설정 파일(lint.xml) 총 세 군데에서 변경 가능합니다. 소스 코드 내에 포함된 설정은 빌드 스크립트 혹은 설정 파일에 정의된 설정과 동시에 적용되지만, 빌드 스크립트에 설정이 적용되어 있다면 별도 설정 파일 내 정의된 설정을 무시하므로 유의해야 합니다.

소스 코드 및 리소스

소스 코드(.java) 및 리소스(.xml) 내에서는 검사에서 제외할 항목을 지정할 수 있습니다.

소스 코드 내에서는 @SuppressLint 어노테이션을 사용하며. 인자로 검사에서 제외할 항목 ID를 입력합니다. 여러 항목을 입력할 경우 입력된 모든 검사 항목을 건너뜁니다.

다음은 소스 코드 내 사용 예를 보여줍니다.

// 하나의 검사 항목만 건너뛸 경우
@SuppressLint("NewApi")
public void foo() {

}

// 여러 검사 항목을 건너뛸 경우
@SuppressLint({"NewApi", "UnusedAttribute"})
public void bar() {

}

리소스 내에서는 tools:ignore 속성을 사용하며, 소스 코드에서와 마찬가지로 검사에서 제외할 항목 ID를 입력합니다. 마찬가지로 여러 항목을 입력할 경우 입력된 모든 검사 항목을 건너뜁니다.

다음은 리소스 내 사용 예를 보여줍니다.

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
  <!-- 하나의 검사 항목만 건너뛸 경우 -->
  <string name="foo" tools:ignore="MissingTranslation">Foo</string>

  <!-- 여러 검사 항목을 건너뛸 경우 -->
  <string name="foo" tools:ignore="MissingTranslation,UnusedResources">Foo</string>
</resources>

빌드 스크립트 (build.gradle)

Gradle 빌드스크립트 내 lintOptions항목 하위에 옵션을 추가하여 사용합니다. android 태그 하위에 넣어주면 되며, 일반적으로 다음과 같은 형태로 선언합니다.

android {
  lintOptions {
    disable 'RtlHardcoded','NewApi'
  }
}

lintOptions에서 지정할 수 있는 옵션 중 대표적인 것들은 다음과 같습니다.

이름 자료형 설명
abortOnError boolean true로 설정하면 lint 에러 발생시 빌드 중단 abortOnError false
disable String[] 검사하지 않을 검사 ID를 입력 disable ‘RtlHardcoded’,’NewApi’
enable String[] 검사를 활성화 할 검사 ID 입력 enable ‘StopShip’
check String[] 입력한 검사ID만 수행 check ‘NewApi’,’StopShip’
lintConfig File Lint 설정 파일 경로 지정 lintConfig file(“default-lint.xml”)

설정 파일 (lint.xml)

설정 파일을 사용하면 검사 옵션을 조금 더 상세하게 설정할 수 있습니다. 설정 파일의 경로를 변경하지 않았다면 모듈의 루트 경로(android 태그를 포함하는 build.gradle 파일과 동일한 단계)에 lint.xml이라는 이름으로 된 파일을 사용합니다.

빌드 스크립트에서의 검사 설정 방법과 유사한 방법으로, 설정 파일에서도 각 검사를 처리할 방법을 설정할 수 있습니다. 각 항목에 대한 중요도를 지정하는 방식으로 설정하며, 중요도는 정보(informational), 경고(warning), 오류(error) 및 무시(ignore) 중 하나로 설정할 수 있습니다.

다음 코드에서 각 검사별 중요도를 변경하는 예제를 확인할 수 있습니다.

<?xml version="1.0" encoding="UTF-8"?>
<lint>
  <!-- 'RtlHardcoded' 검사 중요도를 '무시(ignore)' 로 설정 -->
  <issue id="RtlHardcoded" severity="ignore" />

  <!-- 'StopShip' 검사 중요도를 '오류(error)' 로 설정 -->
  <issue id="StopShip" severity="error" />
</lint>

설정 파일에서는 특정 조건에 맞는 파일에 한해 검사 결과를 무시하도록 설정할 수 있습니다. <issue> 태그 하위에 <ignore> 태그를 사용하여 설정 가능하며, 명시적으로 파일 경로를 정하거나 정규 표현식을 사용하여 조건을 정의할 수 있습니다.

<?xml version="1.0" encoding="UTF-8"?>
<lint>
  <!-- 'src/main/res/values/strings.xml' 파일에 한해 'MissingTranslation' 검사 무시 -->
  <issue id="MissingTranslation">
    <ignore path="src/main/res/values/strings.xml" />
  </ignore>

  <!-- 다음 경로 조건에 부합하는 모든 파일에 대해 'UnusedResources' 검사 무시 -->
  <issue id="UnusedResources">
    <ignore path="src/**/res/values/dimens.xml" />
  </issue>

  <!-- 다음 정규 표현식에 부합하는 모든 파일에 대해 'NewApi' 검사 무시 -->
  <issue id="NewApi">
    <ignore path="src/.*/Source.java" />
  </issue>
</lint>

Android Lint와 관련된 추가 사항들은 다음 링크를 통해 확인할 수 있습니다.

kunny

커니

안드로이드와 오픈소스, 코틀린(Kotlin)에 관심이 많습니다. 전 한국 GDG 안드로이드 운영자 및 GDE 안드로이드로 활동했으며, 현재 구글에서 애드몹 기술 지원을 담당하고 있습니다.

Read More