Android용 Qt의 작동 방식
개발자이시며 Qt가 Android 플랫폼을 어떻게 지원하는지에 대한 전반적인 개요를 찾고 계신다면, 이 페이지가 도움이 될 것입니다.
Qt 애플리케이션 시작
네이티브 Android 앱과 마찬가지로, 앱이 시작되고 Activity가 생성될 때 초기 단계에서 Qt 메인 Activity의 onCreate()가 호출됩니다. 바로 이 시점에서 Android Qt 플랫폼 추상화 (QPA)의 초기화 작업 대부분이 수행됩니다. 가장 중요한 부분은 다음과 같습니다.
- Qt 및 메인 애플리케이션의 라이브러리 불러오기.
- 렌더링 표면과 최상위 레이아웃을 초기화하고, 입력, 디스플레이, 터치 핸들러 등 다양한 리스너를 등록하는 역할을 하는 델리게이트를 초기화합니다.
Qt 라이브러리를 로드할 때, QtCore 가 처음 로드되는 동안 JavaVM이 캐시됩니다. 이는 JNI_OnLoad() 함수 내에서 수행되며, 이 함수는 System.load() 호출을 통해 라이브러리가 로드될 때 동기식으로 호출됩니다. 모든 Qt 모듈은 네이티브 JNI 메서드 등록과 같은 모듈별 초기화 작업을 수행하기 위해 이 함수에 대한 구현을 가질 수 있습니다.
모든 Qt 모듈 라이브러리가 로드되면, Qt는 Android QPA 플러그인과 메인 애플리케이션 라이브러리를 로드합니다. 최상위 QtLayout 레이아웃의 콘텐츠 인플레이션이 완료된 후, Qt 애플리케이션의 main() 핸들이 찾아져 호출됩니다. 이로써 C++ Qt 애플리케이션이 시작되고, 일반적으로 메인 이벤트 루프가 시작됩니다.
Android QPA
Android QPA는 Android(Java/Kotlin) 측과 네이티브 Qt(C++) 측을 연결하는 역할을 담당합니다. 이 레이어는 Qt와 Android 간에 오가는 다양한 이벤트 및 신호 전파를 처리합니다. 이 역할에는 신호 처리, 터치 이벤트, UI 요소, 렌더링 등이 포함됩니다. 또한 이 레이어는 앱 시작 시 초기화와 앱 종료 또는 소멸 시 정리 작업도 담당합니다.
스레드
Android용 Qt 앱의 경우, Qt에서는 일반적으로 두 가지 스레드가 중요합니다. 첫 번째는 Qt가 시작하는 QtThread 입니다. 두 번째는 Android UI 스레드입니다.
QtThread
이 스레드는 예를 들어 라이브러리를 로드하기 전에 Qt 앱에 의해 먼저 구현되고 시작됩니다. 이 스레드는 qtMainLoopThread 라고 불립니다. 다음의 모든 작업은 이 스레드에서 실행됩니다:
- Qt 라이브러리 로딩.
- JNI_OnLoad() 내에서 수행되는 작업.
- 네이티브 애플리케이션 시작.
main()의 실행.
Android UI 스레드
Android 앱과 마찬가지로, UI에 영향을 미치는 작업은 UI 스레드에서 실행되어야 합니다. Qt는 UI에서 실행되어야 하는 모든 내부 호출에 대해 내부적으로 이를 처리합니다. 또한, Qt는 C++ 코드에서 이 스레드 하에서 작업을 실행할 수 있는 API인 runOnAndroidMainThread()를 제공합니다. 이 API를 사용하여 Qt는 앱이 활성 상태일 때는 호출을 스레드에 직접 게시하고, 앱이 일시 중지되었거나 백그라운드에 있을 때는 호출을 대기열에 추가합니다.
아키텍처
Qt 클래스
다음 섹션에서는 다양한 Qt for Android 클래스와 그 기능, 그리고 Qt 애플리케이션 내에서의 역할을 살펴봅니다.
공개 Java 바인딩
이 클래스들은 Activity, Service, Application과 같이 사용자에게 노출되는 클래스의 내부 구현 세부 사항을 래핑하는 공용 클래스입니다. 이 클래스들은 Qt Android 앱에서 기본적으로 사용되며 Android 매니페스트 파일에서 참조됩니다. 빌드 시스템과 배포 도구가 빌드에 이 클래스들을 포함시키는 작업을 처리합니다.
사용자는 이러한 클래스를 사용하여 기본 동작을 변경하거나 확장할 수 있습니다. 예를 들어, QtActivity는 Activity 를 상속하며, Qt 라이브러리를 로드하거나 Android와 Qt 간의 이벤트 및 네이티브 호출을 처리하는 데 필요한 로직을 구현합니다.
Qt와 Android 간의 다양한 이벤트 및 호출에 대해 Qt의 구현이 필요한 경우, 일반적으로 ` QtActivity `을 상속해야 합니다. 그렇지 않은 경우, ` Activity `을 상속하면 됩니다.
onCreate() 아래에 사용자 정의 로직을 추가하려면 다음을 사용할 수 있습니다:
public class MyActivity extends QtActivity
{
@Override
protected void onCreate(Bundle bundle)
{
// code before Qt is initialized
super.onCreate(bundle);
// code after Qt is initialized
}
}참고: 사용자 정의 Activity 또는 바인딩 클래스를 사용하려면 AndroidManifest.xml 파일을 수정해야합니다 . 그렇지 않으면 기본 클래스가 계속 사용됩니다.
테마 설정
QtActivity를 상속할 때 setTheme()을 사용하여 특정 Android 테마를 설정할 수 있습니다. 그러나 Qt는 기본적으로 테마를 설정하므로, 이 호출이 적용되려면 부모 클래스의 onCreate() 호출보다 먼저 이루어져야 합니다. 예를 들어, 다음과 같이 사용할 수 있습니다:
@Override
protected void onCreate(Bundle bundle)
{
setTheme(android.R.style.Theme_DeviceDefault_DayNight);
super.onCreate(bundle);
}기본적으로 Android 10 이상에서는 Qt가 Theme_DeviceDefault_DayNight 스타일을, 그 이전 버전에서는 Theme_Holo_Light 스타일을 테마로 설정합니다.
애플리케이션 매개변수 추가
추가 애플리케이션 매개변수, 즉 Java/Kotlin에서 애플리케이션의 ` (main()) ` 함수로 전달되는 인수를 추가하려면, QtActivity를 상속한 후 다음과 같이 할 수 있습니다:
@Override
protected void onCreate(Bundle bundle)
{
appendApplicationParameters("--flag value");
super.onCreate(bundle);
}이는 CMake 변수 QT_ANDROID_APPLICATION_ARGUMENTS를 직접 사용하는 것과 유사합니다. 두 방법 중 어느 것을 사용하든 전달되는 매개변수는 공백이나 탭을 구분자로 허용하며, 애플리케이션에 전달되는 최종 매개변수 목록은 QProcess::splitCommand 를 통해 구문 분석됩니다.
QtLoader를 사용하여 Qt 라이브러리 불러오기
모든 Qt for Android 앱은 해당 모듈의 기능을 호출하기 전에 모든 네이티브 Qt 라이브러리나 타사 라이브러리가 먼저 로드되었는지 확인해야 합니다. 빌드 시스템은 다양한 Qt 라이브러리 종속성, QPA 플러그인, 메인 앱 라이브러리 및 모든 타사 라이브러리의 목록을 애플리케이션의 libs.xml 리소스 파일에 저장합니다. 아래 섹션에서 언급된 모든 필수 단계가 완료되면 System.load()를 사용하여 라이브러리가 로드됩니다.
클래스 로더
클래스 로더 객체는 Qt 라이브러리를 로드하거나 델리게이트를 초기화하기 전에 ` QtLoader `에 의해 초기 단계에서 설정됩니다. 이는 클래스 로더가 ` QJniObject `에서 Java 클래스를 찾는 데 사용되며, ` QJniObject`을 통한 JNI 호출을 수행하는 데 필요하기 때문입니다.
환경 변수 및 애플리케이션 매개변수 설정
라이브러리를 로드하기 전에, Qt는 설정할 환경 변수가 Android 매니페스트의 메타데이터로 전달되도록 해야 합니다. 이 단계를 통해 매니페스트 메타데이터로 설정된 구성 플래그를 기반으로 일부 모듈을 초기화할 수 있습니다. 이 메타데이터 중 일부는 애플리케이션이 시작될 때 애플리케이션에 전달되는 애플리케이션 매개변수 목록으로도 전달됩니다.
setActivity(), setContext() 및 setService()
다양한 Qt 모듈은 Activity 또는 Service의 컨텍스트가 필요한 초기화 작업을 Java 측에서 수행해야 할 수 있습니다. 이러한 모듈은 Activity, Service 또는 Context를 매개변수로 받는 정적 메서드를 구현합니다:
void setActivity(Activity activity)
{
m_activity = activity;
// Other logic
}그런 다음, 네이티브 공유 라이브러리를 로드하기 직전에 로더( QtLoader )가 로더의 상위 컨텍스트를 사용하여 이러한 메서드를 호출합니다.
Qt for Android가 Android Activity 수명 주기를 처리하는 방식
Qt for Android는 onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy()와 같은 Android 액티비티 라이프사이클 콜백을 직접 처리하는 API를 제공하지 않습니다. 대신, 사용자를 위해 내부적으로 이를 처리합니다. 해당 동작에 대해서는 다음 섹션에서 설명합니다.
참고: 이러한 라이프사이클 이벤트는 ` QGuiApplication::applicationStateChanged ` 신호로 변환됩니다.
컨텍스트 처리
QAndroidApplication QJniObject 형태로 Android 컨텍스트를 제공할 수 있으며, 이는 Android 시스템과 상호작용하는 데 필수적입니다. 이 컨텍스트는 Activity이거나 Service일 수 있습니다. Activity가 있는 경우, Service의 유무와 관계없이 가장 최근에 시작된 Activity가 됩니다. Service만 있는 경우, 가장 최근에 시작된 Service가 됩니다.
참고: Qt for Android는 여러 개의 액티비티를 지원하지 않습니다.
콜백
QtActivityBase 클래스는 Activity의 다양한 기능에 대한 구현 세부 사항을 Qt for Android 패키지 내에서 비공개로 유지하도록 설계되었습니다. 이 클래스는 Android 라이프사이클과 Qt 프레임워크 사이의 중개자 역할을 하며, Android 라이프사이클 콜백을 Qt 애플리케이션이 응답할 수 있는 신호와 작업으로 변환합니다.
onCreate()
Activity가 생성되면 QtActivityBase는 Qt 환경을 초기화합니다. 여기에는 Qt 라이브러리 로딩, QJniObject 가 사용하는 클래스 로더 설정, 앱 메타데이터 파싱, Qt 애플리케이션 실행 준비 등이 포함됩니다. 이를 통해 Activity에 특화된 모든 필수 초기화 작업이 처리되도록 보장합니다.
onStart()
Android의 Activity.OnStart()를 호출합니다.
onResume()
Activity가 전경으로 이동하면, QtActivityBase는 Qt 애플리케이션을 재개합니다. 이를 통해 일시 중지된 프로세스나 작업이 계속 진행되고, 애플리케이션이 다시 사용자 상호작용을 받을 준비가 되도록 보장합니다. 또한 onPause()에 의해 중지되었던 디스플레이 매니저 리스너를 다시 등록합니다.
onPause()
다른 액티비티가 해당 액티비티를 부분적으로 가릴 경우, QtActivityBase는 Qt 애플리케이션을 일시 중지합니다. 이 때 애플리케이션 상태를 저장하거나, 애플리케이션이 전경에 있지 않은 동안 필요하지 않은 리소스를 해제합니다.
onStop()
액티비티가 더 이상 표시되지 않으면, QtActivityBase는 Qt 애플리케이션을 중지합니다. 이 과정에는 더 광범위한 상태 저장 및 리소스 해제가 포함되며, 애플리케이션이 잠재적으로 소멸될 수 있도록 준비합니다.
참고: 이 시점에서QtThread는 일시 중지됩니다.
onDestroy()
액티비티가 종료되거나 시스템에 의해 파기되는 경우, QtActivityBase는 Qt 애플리케이션과 관련된 모든 리소스를 정리합니다. 이를 통해 적절한 종료가 이루어지고 필요한 모든 정리 작업이 수행되도록 보장합니다.
이러한 통합 덕분에 QtActivityBase가 내부적으로 이러한 복잡한 작업을 관리하므로, 개발자는 Android 라이프사이클의 복잡한 세부 사항에 대해 걱정할 필요 없이 Qt 애플리케이션 구축에 집중할 수 있습니다.
스플래시 화면 관리
QAndroidApplication 는 페이드 효과를 사용하여 스플래시 화면을 숨길 수 있으며, 이 효과는 애플리케이션의 시작 순서(일반적으로 onCreate() 이후)에 맞춰 타이밍을 조정할 수 있습니다.
Qt for Android에 대한 자세한 정보
2021 Qt World Summit의 동영상은 Qt for Android에 대한 개요를 제공합니다.
"YouTube 동영상으로 연결되는 의제 이미지"
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.