Android/Custom System Service

Android 사용자 정의 System Service 만들기

임베디드 친구 2025. 6. 4. 21:56
728x90
반응형

Android 사용자 정의 System Service 만들기

Android에서 시스템 서비스를 직접 구현하고 등록하는 과정은 고급 개발자에게 중요한 기술입니다. 이 글에서는 Android 서비스 아키텍처를 개괄하고, System Service를 생성 및 등록하는 방법, 그리고 AIDL을 활용한 IPC(Inter-Process Communication) 개념을 정리하겠습니다.

1. Android 서비스 아키텍처 개요

Android의 서비스 아키텍처는 Binder, ServiceManager, SystemServer를 중심으로 구성됩니다. 이들은 Android에서 프로세스 간 통신(IPC)과 서비스 관리를 담당하는 핵심 요소들입니다.

1.1 Binder

Binder는 Android에서 IPC를 가능하게 하는 핵심 메커니즘입니다. Android의 모든 시스템 서비스는 Binder를 기반으로 동작하며, 클라이언트와 서버 간의 데이터를 안전하게 주고받을 수 있도록 설계되어 있습니다.

Binder의 주요 기능은 다음과 같습니다.

  • 객체 참조 전달: 프로세스 간에 객체 참조를 전달할 수 있도록 지원합니다.
  • 성능 최적화: 기존의 UNIX 소켓이나 파이프 기반 IPC보다 높은 성능을 제공합니다.
  • 보안 관리: UID/GID 기반의 접근 제어를 제공합니다.

1.2 ServiceManager

ServiceManager는 Android의 중앙 서비스 레지스트리 역할을 합니다. 시스템 서비스는 ServiceManager에 등록되며, 클라이언트는 이를 통해 필요한 서비스를 검색할 수 있습니다.

ServiceManager의 동작 방식은 다음과 같습니다.

  1. 시스템 서비스가 시작될 때 ServiceManager에 등록됨.
  2. 클라이언트가 특정 서비스가 필요할 때 ServiceManager를 통해 검색.
  3. 서비스의 Binder 객체를 반환받아 IPC를 수행.

1.3 SystemServer

SystemServer는 Android 부팅 과정에서 다양한 시스템 서비스를 초기화하는 핵심 프로세스입니다. SystemServer는 부팅 후 여러 시스템 서비스를 시작하고 ServiceManager에 등록합니다.

SystemServer의 역할은 다음과 같습니다.

  • 핵심 시스템 서비스 실행: PowerManagerService, ActivityManagerService, WindowManagerService 등의 서비스 실행.
  • 서비스 등록: 생성된 서비스를 ServiceManager에 등록.

2. 기본적인 System Service의 등록 과정

사용자 정의 시스템 서비스를 만들기 위해서는 다음과 같은 단계를 거쳐야 합니다.

2.1 System Service 클래스 생성

사용자 정의 서비스를 만들기 위해 SystemService 클래스를 상속받아야 합니다.

public class MySystemService extends SystemService {
    public MySystemService(Context context) {
        super(context);
    }

    @Override
    public void onStart() {
        publishBinderService("myservice", new IMyService.Stub() {
            @Override
            public String getMessage() throws RemoteException {
                return "Hello from MySystemService!";
            }
        });
    }
}

위 코드에서 publishBinderService() 메서드를 사용하여 ServiceManager에 시스템 서비스를 등록합니다.

2.2 SystemServer에 서비스 등록

SystemServer에서 사용자 정의 서비스를 초기화하는 과정은 다음과 같습니다.

  1. SystemServerstartOtherServices() 메서드에서 새로운 서비스를 추가합니다.
private void startOtherServices() {
    MySystemService myService = new MySystemService(mContext);
    myService.onStart();
}
  1. Android.mk 파일을 수정하여 컴파일할 수 있도록 추가합니다.
LOCAL_SRC_FILES := \
    MySystemService.java
  1. init.rc 파일을 수정하여 SystemServer가 실행될 때 서비스를 초기화할 수 있도록 합니다.
service myservice /system/bin/my_service
    class main
    user system
    group system
    oneshot

3. AIDL을 활용한 IPC 개념 정리

AIDL (Android Interface Definition Language)은 Android에서 IPC를 수행하기 위한 언어입니다. 이를 이용하면 프로세스 간 메서드 호출을 구현할 수 있습니다.

3.1 AIDL 파일 생성

IMyService.aidl 파일을 생성하고, 아래와 같이 인터페이스를 정의합니다.

package com.example.mysystemservice;

interface IMyService {
    String getMessage();
}

3.2 AIDL 인터페이스 구현

이제 IMyService를 구현하는 클래스를 생성해야 합니다.

public class MySystemService extends SystemService {
    private final IMyService.Stub mBinder = new IMyService.Stub() {
        @Override
        public String getMessage() throws RemoteException {
            return "Hello from MySystemService!";
        }
    };

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

    @Override
    public void onStart() {
        publishBinderService("myservice", mBinder);
    }
}

3.3 클라이언트에서 서비스 접근

클라이언트는 ServiceManager를 통해 MySystemService를 검색하고, 이를 통해 getMessage() 메서드를 호출할 수 있습니다.

IBinder binder = ServiceManager.getService("myservice");
IMyService myService = IMyService.Stub.asInterface(binder);
String message = myService.getMessage();
Log.d("MyClient", "Received: " + message);

4. 결론

Android에서 사용자 정의 System Service를 만드는 과정은 SystemService 클래스를 생성하고, 이를 SystemServer에 등록하며, AIDL을 활용하여 IPC를 구현하는 방식으로 진행됩니다. 이를 활용하면 Android 시스템 내부에서 동작하는 커스텀 서비스를 만들 수 있으며, 클라이언트 애플리케이션이 이를 사용할 수 있도록 지원할 수 있습니다.

728x90
반응형