Android/Custom System Service

Android 사용자 정의 System Service 만들기

임베디드 친구 2025. 6. 7. 16:37
728x90
반응형

Android 사용자 정의 System Service 만들기

Android에서 사용자 정의 System Service를 구현하는 방법 중 하나는 JNI (Java Native Interface)를 이용하여 Native System Service를 구축하는 것입니다. 이를 통해 기존 Android Native Service와 연동하고, C++ 기반의 서비스를 Android 프레임워크와 통합할 수 있습니다. 본 포스팅에서는 다음과 같은 주요 내용을 다룹니다.

  1. JNI를 이용한 Native System Service 구현 방법
  2. 기존 Android Native Service와의 연동 방식
  3. C++로 구현된 서비스의 Binder IPC 연동
  4. Native 코드에서 System Service를 등록하는 방법

1. JNI를 이용한 Native System Service 구현 방법

JNI를 활용하여 Native System Service를 구현하는 첫 번째 단계는 Java와 Native 코드 간의 인터페이스를 정의하는 것입니다. 일반적으로 System Service는 Java로 작성되지만, 일부 성능이 중요한 서비스나 기존 네이티브 코드와의 연동이 필요한 경우 JNI를 통해 C++ 로직을 호출할 수 있습니다.

(1) Java System Service 정의

우선, SystemService를 상속하는 클래스를 정의하고, 네이티브 메서드를 선언합니다.

public class NativeExampleService extends SystemService {
    static {
        System.loadLibrary("native_example"); // 네이티브 라이브러리 로드
    }

    public NativeExampleService(Context context) {
        super(context);
    }

    @Override
    public void onStart() {
        nativeStartService(); // 네이티브 서비스 시작
    }

    private native void nativeStartService(); // JNI 메서드 선언
}

이제 네이티브 C++ 코드에서 nativeStartService()를 구현해야 합니다.

(2) JNI 구현 (C++)

JNI 인터페이스를 구현하려면, native_example.cpp 파일을 생성하고 Java의 네이티브 메서드를 정의해야 합니다.

#include <jni.h>
#include <android/log.h>

#define LOG_TAG "NativeExampleService"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

extern "C" JNIEXPORT void JNICALL
Java_com_example_NativeExampleService_nativeStartService(JNIEnv *env, jobject obj) {
    LOGI("Native System Service Started");
    // 여기에 네이티브 서비스 로직 추가
}

(3) Android.mk 또는 CMakeLists.txt 설정

Android NDK에서 JNI를 빌드하려면 Android.mk 또는 CMakeLists.txt 파일을 설정해야 합니다.

Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := native_example
LOCAL_SRC_FILES := native_example.cpp

include $(BUILD_SHARED_LIBRARY)

CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

add_library(native_example SHARED native_example.cpp)

find_library(log-lib log)

target_link_libraries(native_example ${log-lib})

2. 기존 Android Native Service와의 연동 방식

Android에서는 system_server에서 실행되는 Java 기반의 System ServiceNative Service 간의 통신이 필요합니다. 이를 위해 Binder IPC를 사용할 수 있습니다.

(1) Binder IPC를 활용한 연동

Android의 Binder는 프로세스 간 통신(IPC)을 위한 주요 메커니즘입니다. 기존 System Service(Java)와 Native Service(C++) 간에 데이터를 교환하려면 Binder를 통해 메시지를 주고받을 수 있습니다.

(2) 기존 서비스에서 Native 서비스 호출

IBinder binder = ServiceManager.getService("native_example");
if (binder != null) {
    INativeExampleService service = INativeExampleService.Stub.asInterface(binder);
    service.performNativeTask();
}

이제 C++에서 Binder 인터페이스를 제공해야 합니다.

3. C++로 구현된 서비스의 Binder IPC 연동

(1) AIDL을 활용한 서비스 정의

AIDL을 활용하여 Java와 C++ 간의 인터페이스를 정의할 수 있습니다. 예제 AIDL 파일을 생성합니다.

INativeExampleService.aidl

interface INativeExampleService {
    void performNativeTask();
}

(2) C++에서 Binder 서비스 구현

Binder 기반의 Native 서비스를 작성하기 위해 BpInterfaceBnInterface를 구현합니다.

class NativeExampleService : public BnInterface<INativeExampleService> {
public:
    status_t performNativeTask() override {
        LOGI("Performing native task");
        return OK;
    }
};

4. Native 코드에서 System Service를 등록하는 방법

(1) ServiceManager에 등록

ServiceManager에 네이티브 서비스를 등록하여 다른 Android 구성 요소에서 접근할 수 있도록 합니다.

int main() {
    sp<IServiceManager> sm = defaultServiceManager();
    sp<NativeExampleService> service = new NativeExampleService();
    sm->addService(String16("native_example"), service);

    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
    return 0;
}

(2) init.rc에 서비스 등록

서비스가 부팅 시 자동으로 시작되도록 init.rc에 등록합니다.

service native_example /system/bin/native_example_service
    class core
    user system
    group system
    oneshot

결론

본 포스팅에서는 JNI를 이용한 Native System Service의 구현 방법Binder IPC를 활용한 기존 서비스와의 연동 방식을 다루었습니다. 이를 통해 Android 시스템에서 C++로 구현된 네이티브 서비스를 등록하고, Java 기반의 System Service와 통신하는 방법을 설명했습니다.

이러한 기법을 활용하면 성능이 중요한 서비스를 네이티브로 작성하면서도 Android 프레임워크와 원활하게 연동할 수 있습니다. 프로젝트에 따라 필요에 맞게 커스터마이징하여 활용할 수 있습니다.

반응형