본문 바로가기
Android개발

Android Lint #1 - 기본

by 궝테스트 2020. 7. 2.

1. Android Lint 란 무엇인가?

  • Android Studio 에서 제공하는 Lint 라는 코드 스캔 도구
  • 앱 실행 또는 테스트 케이스 작성 없이 코드의 구조적 품질 문제를 감지하고 수정 가능
  • 감지된 문제들은 설명과 함께 심각도 레벨이 함께 보고되므로 우선순위를 정할 수 있다
  • 프로젝트와 관련 없는 문제의 심각도 레벨 조정하여 특정 문제에 대해 강조 표시할 수 있다
  • 기본적으로 Android Studio 에서 앱 빌드 시, 기본 Lint 및 IDE 검사가 실행된다
  • 수동으로 검사 또는 Command line 으로 실행할 수도 있다

Code scanning workflow with the lint tool

App source files

: Java, Kotlin, XML, Proguard 구성 파일 및 icon 파일을 포함한 Android 프로젝트를 구성하는 파일로 이루어진다.

lint.xml

: 제외 할 lint 검사를 지정하고 문제 심각도 레벨을 맞춤 설정하는 구성 파일

Lint tool

  • Android Studio 또는 Command line 을 사용하여 실행할 수 있는 정적 코드 스캔 도구
  • 앱의 품질과 성능에 영향을 미칠 수 있는 코드의 구조적 문제를 검사한다
  • 앱을 구글 플레이에 게시하기 전에 Lint 가 발견한 에러를 수정하자

Lint output

: Console 또는 Android Studio 의 Inspection Results 창에서 확인할 수 있다

 

2. How to run Lint

2-1. Run lint from the command line

Android Studio 또는 Gradle 을 사용하고 있다면, Graddle wrapper 를 사용하여
프로젝트의 루트 디렉터리에서 아래 command line 으로 lint 작업을 호출할 수 있다.
buildType 중 특정 build variant 의 lint 를 실행하려면 뒤에 해당 type 을 넣어준다.

./gradlew lint
./gradlew lintDebug
./gradlew lintRelease

위 command line 의 결과는 아래와 같다.

> Task :app:lint
    Ran lint on variant release: 5 issues found
    Ran lint on variant debug: 5 issues found
    Wrote HTML report to file:<path-to-project>/app/build/reports/lint-results.html
    Wrote XML report to file:<path-to-project>/app/build/reports/lint-results.xml

Lint tool 에서 검사가 완료되면 XML 과 HTML 로 Lint 보고서 경로가 제공되고 내용을 확인할 수 있다.
만약 프로젝트 내에서 module 을 나눠서 사용하고 있다면, module 별로 각 Lint 보고서 경로가 제공된다.

Sample HTML lint report

 

2-2. Run lint using the standalone tool

Android Studio, Gradle 을 사용하지 않는 경우,
SDK Manager 에서 Android SDK Tools 를 설치하고 독립형 lint tool 을 사용하면 된다.
android_sdk_path/tools/ 디렉터리에서 lint tool 을 찾을 수 있다.

 

3. Configure the lint file

  • 기본 구성의 lint 를 실행하면 지원하는 모든 문제를 검사한다
  • 프로젝트와 관련 없는 특정 문제를 검사되지 않게 구성하거나 심각도 레벨이 낮아 보고되지 않는 문제를 보고하도록 구성할 수 있다

3-1. Configure the lint file

  • Android Studio 를 사용하는 동안 내장된 lint tool 이 코드를 검사한다.
  • Warning 과 Error 를 확인할 수 있는 방법은 2가지이다.
    • 코드에서 팝업 텍스트로 확인 : Warning=노랑노랑, Error=빨강
    • 수동 검사 실행

3-2. Manually run inspection

메뉴 Analyze > Inspect Code > Specify Inspection Scope 로 진입 가능

Analyze > Inspect Code > Specify Inspection Scope

  • Whole project : 전체 프로젝트 검사
  • Module 'test-android-app' : 기본 app module 검사
  • Uncommitted files : 커밋되지 않은 파일 검사
    • 버전 관리중인 프로젝트에서만 사용 가능
    • Default : IntelliJ IDEA 에 의한 기본 변경 파일만 검사
    • All : 모든 변경 파일 검사
  • File '...' : 프로젝트 창에서 현재 선택되어있는 파일 검사
  • Custom scope : 지정된 범위만 검사
  • Include test sources : 테스트 코드 포함 여부
  • Inspection profile :  Android 업데이트로 인해 업데이트된 lint 파일로 그대로 사용 또는 범위 수정 가능

3-3. Configure the lint.xml

  • lint.xml 파일로 구성할 수 있으며 수동으로 만들 경우 프로젝트 루트 디렉터리에 넣는다
  • <lint> 의 하위 요소로 <issue> 가 하나 이상 포함되어야 하며, <issue id="..."> id 속성 값을 정의해야한다
  • 또한 <issue> 에 심각도 레벨 severity 을 설정할 수 있다
<?xml version="1.0" encoding="UTF-8"?>
<lint>
	<!-- Disable the given check in this project -->
	<issue id="IconMissingDensityFolder" severity="ignore" />
        
	<!-- Ignore the ObsoleteLayoutParam issue in the specified files -->
	<issue id="ObsoleteLayoutParam">
		<ignore path="res/layout/activation.xml" />
		<ignore path="res/layout-xlarge/activation.xml" />
	</issue>

	<!-- Ignore the UselessLeaf issue in the specified file -->
	<issue id="UselessLeaf">
		<ignore path="res/layout/main.xml" />
	</issue>

	<!-- Change the severity of hardcoded strings to "error" -->
	<issue id="HardcodedText" severity="error" />
</lint>

 

3-4. Configuring lint checking in Code

In Java or Kotlin

  • class 또는 method 코드 내에서 lint 검사를 중지하려면 @SuppressLint 어노테이션을 추가한다
  • 모든 검사를 중지하려면 @SuppressLint("all") 를 추가한다
// NewApi 검사 중지
@SuppressLint("NewApi")
override fun onCreate(savedInstanceState: Bundle?) {
	super.onCreate(savedInstanceState)
	setContentView(R.layout.main)
}

// ParserError 검사 중지
@SuppressLint("ParserError")
class FeedProvider : ContentProvider() {}

 

In XML

  • xml 에서 lint 검사를 중지하려면 tools:ignore 속성을 추가한다
  • 모든 검사를 중지하려면 tools:ignore="all" 을 추가한다
  • 관련 namespace 인 namespace xmlns:tools="http://schemas.android.com/tools" 도 추가한다
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:tools="http://schemas.android.com/tools"
	tools:ignore="UnusedResources" >

	<TextView
    	tools:ignore="NewApi,StringFormatInvalid"
		android:text="@string/auto_update_prompt" />
</LinearLayout>

 

4. Configure lint options with Gradle

  • module 수준의 build.gradle 파일에서 lintOptions {} 블록을 사용하여 구성할 수 있다
  • abortOnError 를 끄지 말자!
    • abortOnError : 심각 레벨이 Error/Fatal 이라면 Build 중단
    • checkReleaseBuilds : Release build 시에 Fatal 이라면 Build 중단
android {
    lintOptions {
        // disable : 해당 문제 검사 중지
        disable 'TypographyFractions','TypographyQuotes'
        
        // enable : 검사에 포함 
        enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
        
        // 해당 문제의 하위 집합만 검사하고 다른 문제는 무시
        check 'NewApi', 'InlinedApi'
        
        // true 로 설정하면 lint 에 의한 분석 진행률 보고를 끈다
        quiet true
        
        // true(기본값) 로 설정하면 에러 발견 시 빌드 중지
        abortOnError false
        
        // true 이면 에러만 보고하고 warning 은 보고하지 않음
        ignoreWarnings true
    }
}
  • Create warnings baseline
    • 프로젝트의 현재 warning 세트의 스냅샷을 만든 후, 이후 검사할 때 기준으로 사용해서 새로운 문제만 보고되도록 만들 수 있다
    • 아래처럼 추가하면 lint-baseline.xml 파일이 만들어지고 다음에는 해당 파일만 읽어서 기준을 확인한다
    • 새로운 baseline 을 만들려면 수동으로 해당 파일을 삭제 후 다시 lint 실행하여 만들면 된다
android {
	lintOptions {
		baseline file("lint-baseline.xml")
	}
}

 

5. Inspection Result

5-1. Category

Lint output 으로 아래와 같이 카테고리화되어 나온다.

Correctness 라이브러리 API 등 올바른 사용법 체크
Security JavaScriptEnabled 등 보안 관련 체크
Performance 메모리 할당, 불필요한 SDK_INT 버전 체크, 미사용 리소스 등 성능 관련 체크
Usablility 위젯의 빠진 속성 등 사용성 관련 체크
Accessiblility 접근성 관련 체크
Internationalization 하드 코딩된 텍스트, Right-to-Left 모드, 국제화 및 다국어 관련 체크

Severity

Fatal 치명적이며 Build/Run 시 반드시 실패
Error Build 는 가능하지만 Run 시 에러를 일으킬 가능성 큼
Warning 동작은 가능하지만 수정하는게 보다 좋은 앱을 만든다 (weak warning 도 있음)
Info 거의 문제 없지만 알아두어라-
Ignore 문제가 있어도 보고하지 않는다

 

참고)
Android Developers : https://developer.android.com/studio/write/lint

 

'Android개발' 카테고리의 다른 글

Migrating build.gradle from Groovy to Kotlin  (0) 2020.09.25
Android Lint #2 - Custom Lint  (0) 2020.07.03
App Startup time  (1) 2020.06.25
App Startup  (0) 2020.06.25
Elevation  (0) 2020.03.18

댓글