Android 스튜디오에서는 Kotlin을 완벽하게 지원하므로 기존 프로젝트에 Kotlin 파일을 추가하고 자바 언어 코드를 Kotlin으로 변환할 수 있습니다. 그런 다음 Kotlin 코드와 함께 자동 완성, 린트 검사, 리팩터링, 디버깅 등 Android 스튜디오의 기존 도구를 모두 사용할 수 있습니다.
새로운 프로젝트를 시작하면서 Kotlin을 사용하려면 프로젝트 만들기를 참고하세요.
샘플은 Kotlin 코드 샘플에서 확인하세요.
기존 프로젝트에 Kotlin 추가
프로젝트에 Kotlin을 추가하려면 다음 단계를 따르세요.
File > New를 클릭하고 그림 1과 같이 다양한 Android 템플릿(예: 새로운 빈 Fragment) 중 하나를 선택합니다. 이 메뉴에 템플릿 목록이 보이지 않으면 먼저 Project 창을 열고 앱 모듈을 선택합니다.
마법사가 표시되면 Source Language로 Kotlin을 선택합니다. 그림 2에서는 새로운 활동을 만들려고 할 때 표시되는 New Android Activity 대화상자를 보여줍니다.
마법사를 계속 진행합니다.
또는 File > New > Kotlin File/Class를 클릭하여 기본 Kotlin 파일을 만들 수 있습니다. 이 옵션이 표시되지 않으면 Project 창을 열고 java 디렉터리를 선택합니다. New Kotlin File/Class 창에서 파일 이름을 정의하고 여러 파일 형식 중에 선택할 수 있습니다. 예를 들면 다음과 같습니다. File, Class, Interface, Enum Class, Object. 선택에 따라 새로운 Kotlin 파일에서 만들어지는 기본 스캐폴딩이 달라집니다. Class를 선택하면 Android 스튜디오는 주어진 이름 및 일치하는 클래스 정의로 새로운 Kotlin 소스 파일을 만듭니다. Interface를 선택하면 인터페이스가 파일에 선언됩니다.
Android 템플릿을 사용하지 않고 이번에 처음으로 직접 프로젝트에 새로운 Kotlin 클래스나 파일을 추가한 경우 그림 3과 같이 Android 스튜디오에서 Kotlin이 프로젝트에 구성되어 있지 않다는 경고를 표시합니다. 편집기의 오른쪽 상단에서 또는 오른쪽 하단에 표시되는 event log alert에서 Configure를 클릭하여 Kotlin을 구성합니다.
그림 4와 같이 메시지가 표시되면 All modules containing Kotlin files로 Kotlin 구성 옵션을 선택합니다.
OK를 클릭하면 Android 스튜디오에서 Kotlin을 프로젝트 클래스 경로에 추가하고 Kotlin 파일이 포함된 각 모듈에 Kotlin Android 플러그인을 적용합니다.
build.gradle
파일은 아래 예와 유사합니다.
Groovy
// Project build.gradle file. buildscript { ext.kotlin_version = '1.4.10' ... dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } }
Kotlin
// Project build.gradle.kts file. buildscript { extra["kotlin_version"] = "1.4.10" ... dependencies { classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version") } }
Groovy
// Inside each module using kotlin plugins { ... id 'kotlin-android' } ... dependencies { implementation 'androidx.core:core-ktx:1.3.2' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" }
Kotlin
// Inside each module using kotlin plugins { ... kotlin("android") } ... val kotlin_version: String by rootProject.extra dependencies { implementation("androidx.core:core-ktx:1.3.2") implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version") }
소스 구성
기본적으로 새로운 Kotlin 파일은 src/main/java/
에 저장되므로 Kotlin과 자바 파일을 모두 한 위치에서 쉽게 확인할 수 있습니다. Kotlin 파일을 자바 파일과 분리하려면 Kotlin 파일을 src/main/kotlin/
에 대신 넣을 수 있습니다. 이렇게 하면 아래 예와 같이 이 디렉터리를 sourceSets
구성에도 포함해야 합니다.
Groovy
android { sourceSets { main.java.srcDirs += 'src/main/kotlin' } }
Kotlin
android { sourceSets { getByName("main") { java.srcDir("src/main/kotlin") } } }
기존 자바 코드를 Kotlin 코드로 변환
자바 코드를 Kotlin으로 변환하려면 Android 스튜디오에서 자바 파일을 열고 Code > Convert Java File to Kotlin File을 선택합니다. 또는 새로운 Kotlin 파일을 만들고(File > New > Kotlin File/Class) 만들어진 파일에 자바 코드를 붙여넣습니다. 그러면 그림 5와 같이 Android 스튜디오에서 메시지를 표시하여 코드를 Kotlin으로 변환하라고 제안합니다. Yes를 클릭하여 변환합니다. Don't show this dialog next time을 선택하여 이후 변환을 자동으로 실행할 수 있습니다.
코드 변환 및 null 허용 여부
Android 스튜디오의 변환 프로세스는 컴파일되고 실행되는 기능적으로 동등한 Kotlin 코드를 생성합니다. 그러나 변환된 코드를 추가로 최적화해야 할 수 있습니다. 예를 들어 변환된 코드가 null 허용 가능 유형을 처리하는 방법을 개선하는 것이 좋습니다.
Android에서는 연결된 프래그먼트나 활동이 적절한 수명 주기 상태에 도달할 때까지 View
객체와 다른 구성요소의 초기화를 지연시키는 것이 일반적입니다. 예를 들어 다음 스니펫과 같이 프래그먼트 중 하나의 버튼 참조가 있을 수 있습니다.
public class JavaFragment extends Fragment {
// Null until onCreateView.
private Button button;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_content, container,false);
// Get a reference to the button in the view, only after the root view is inflated.
button = root.findViewById(R.id.button);
return root;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Not null at this point of time when onViewCreated runs
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
...
}
});
}
}
버튼 변수가 null을 허용하더라도 실제로 이 예에서 사용될 때는 null이 되어서는 안 됩니다. 그러나 구성 시점에서 값이 할당되지 않으므로 생성된 Kotlin 코드는 Button
을 null을 허용하는 유형으로 취급하고 아래와 같이 클릭 리스너를 추가할 때 null이 아닌 어설션 연산자를 사용하여 버튼을 래핑 해제합니다.
class JavaFragment : Fragment() {
// Null until onCreateView.
private var button: Button? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
...
// Get a reference to the button in the view, only after the root view is inflated.
button = root.findViewById(R.id.button)
...
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Not null at the point of time when onViewCreated fires
// but force unwrapped nonetheless
button!!.setOnClickListener { }
}
}
이 경우에 lateinit
를 사용하는 것보다 이 변환은 이상적이지 않습니다. 액세스되는 곳마다 null이 아닌 어설션이나 안전 호출 연산자를 사용하여 버튼 참조를 래핑 해제해야 하기 때문입니다.
null
이 애플리케이션의 사용 사례에 기반한 유효한 변수 할당인 다른 경우에는 종료 elvis 연산자와 함께 안전 호출 (?.) 연산자를 사용하면 (?:) 연산자가 null을 허용하는 객체를 안전하게 래핑 해제하거나 적절한 null이 아닌 기본값으로 강제 변환하는 더 적합한 방법일 수 있습니다. Android 스튜디오에는 변환 프로세스 중에 이 판단을 내릴 수 있는 정보가 충분하지 않습니다. null이 아닌 어설션이 기본값이 되지만 필요에 따라 변환된 코드를 추적하고 조정해야 합니다.
추가 정보
프로젝트에서 Kotlin과 자바 코드를 모두 사용하는 방법에 관한 자세한 내용은 Kotlin에서 자바 코드 호출을 참고하세요.
엔터프라이즈 시나리오에서 Kotlin을 사용하려면 대규모 팀에 Kotlin 채택에서 자세한 내용을 확인하세요.
기존 Android API의 직관적인 Kotlin 래퍼에 관한 자세한 내용은 Android KTX를 참고하세요.