Android/User Daemon

실전 프로젝트: 간단한 Android Daemon 구현

임베디드 친구 2025. 6. 25. 19:34
728x90
반응형

실전 프로젝트: 간단한 Android Daemon 구현

1. 예제 프로젝트 개요

Android에서 백그라운드에서 실행되는 Daemon 프로세스를 구현하는 것은 시스템 작업을 수행하거나 지속적인 서비스 기능을 제공할 때 유용합니다. 이번 포스팅에서는 Android NDK를 활용하여 간단한 Daemon 프로세스를 C/C++로 구현하고, 이를 Java/Kotlin과 연동하여 실행하는 방법을 설명하겠습니다.

1.1 프로젝트 목표

  • Android NDK를 이용하여 C/C++ 기반의 Daemon을 개발
  • Android 애플리케이션과 연동하여 Daemon 실행 및 종료
  • Daemon이 백그라운드에서 지속적으로 동작하도록 설정
  • Java/Kotlin에서 C/C++ Daemon을 실행하고 로그 확인

1.2 개발 환경

  • Android Studio (최신 버전)
  • Android NDK
  • CMake 및 Gradle 설정
  • Android 기기 또는 에뮬레이터 (root 권한이 없는 일반 사용자 환경에서 동작)

2. C/C++로 Daemon 개발 및 빌드

Android NDK에서 Daemon을 구현하기 위해, 먼저 C/C++로 실행 가능한 바이너리를 작성한 후 이를 빌드하는 과정을 진행하겠습니다.

2.1 Daemon C++ 코드 작성

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <android/log.h>

#define LOG_TAG "DaemonExample"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

void startDaemon() {
    pid_t pid = fork();
    if (pid < 0) {
        LOGE("Fork failed");
        exit(1);
    }
    if (pid > 0) {
        LOGI("Parent process exiting, Daemon PID: %d", pid);
        exit(0);
    }
    // 세션을 새롭게 생성
    if (setsid() < 0) {
        LOGE("Failed to create new session");
        exit(1);
    }
    chdir("/");
    umask(0);
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);

    while (1) {
        LOGI("Daemon Running...");
        sleep(5);
    }
}

int main() {
    startDaemon();
    return 0;
}

2.2 CMakeLists.txt 설정

cmake_minimum_required(VERSION 3.10.2)
project(DaemonExample)

add_library(daemon SHARED src/main/cpp/daemon.cpp)

find_library(log-lib log)

target_link_libraries(daemon ${log-lib})

2.3 Android.mk 설정 (NDK 빌드를 사용할 경우)

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

LOCAL_MODULE    := daemon_example
LOCAL_SRC_FILES := daemon.cpp

LOCAL_LDLIBS    := -llog

include $(BUILD_SHARED_LIBRARY)

2.4 빌드 및 실행

CMake 또는 NDK 빌드 도구를 이용하여 Daemon을 빌드한 후, Android 애플리케이션에서 실행할 수 있도록 준비합니다.

3. Java/Kotlin과 연동하여 실행 및 테스트

Daemon을 실행하려면 Java/Kotlin에서 해당 바이너리를 실행할 수 있도록 처리해야 합니다.

3.1 Daemon 실행을 위한 Java 코드

package com.example.daemonapp;

import android.content.Context;
import android.util.Log;
import java.io.File;
import java.io.IOException;

public class DaemonManager {
    private static final String TAG = "DaemonManager";

    public static void startDaemon(Context context) {
        File daemonFile = new File(context.getFilesDir(), "daemon");
        if (!daemonFile.exists()) {
            Log.e(TAG, "Daemon binary not found");
            return;
        }
        daemonFile.setExecutable(true);
        try {
            Process process = new ProcessBuilder(daemonFile.getAbsolutePath()).start();
            Log.i(TAG, "Daemon started with PID: " + process.pid());
        } catch (IOException e) {
            Log.e(TAG, "Failed to start daemon", e);
        }
    }
}

3.2 Kotlin에서 Daemon 실행

package com.example.daemonapp

import android.content.Context
import android.util.Log
import java.io.File

object DaemonManager {
    private const val TAG = "DaemonManager"

    fun startDaemon(context: Context) {
        val daemonFile = File(context.filesDir, "daemon")
        if (!daemonFile.exists()) {
            Log.e(TAG, "Daemon binary not found")
            return
        }
        daemonFile.setExecutable(true)
        try {
            val process = ProcessBuilder(daemonFile.absolutePath).start()
            Log.i(TAG, "Daemon started with PID: ${process.pid()}")
        } catch (e: IOException) {
            Log.e(TAG, "Failed to start daemon", e)
        }
    }
}

3.3 애플리케이션에서 Daemon 실행

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    DaemonManager.startDaemon(this);
}

4. 마무리 및 정리

이번 포스팅에서는 Android에서 NDK를 활용하여 간단한 Daemon을 개발하고, 이를 Java/Kotlin 애플리케이션에서 실행하는 방법을 살펴보았습니다. Daemon을 활용하면 지속적인 백그라운드 작업을 수행할 수 있으며, 다양한 시스템 작업을 효율적으로 처리할 수 있습니다.

728x90
반응형