Android/Custom Framework

Android 사용자 정의 Framework Service 최적화 및 성능 개선

임베디드 친구 2025. 6. 1. 15:20
728x90
반응형

Android 사용자 정의 Framework Service 최적화 및 성능 개선

Android의 사용자 정의 Framework Service는 시스템의 전반적인 성능과 안정성에 큰 영향을 미칠 수 있습니다. 특히, SystemServer 내에서 동작하는 서비스는 부팅 시간, Binder 트랜잭션 처리 속도, ANR 방지 등을 고려하여 최적화해야 합니다. 이 글에서는 Android 사용자 정의 Framework Service의 성능을 개선하는 방법과 최적화 기법을 소개합니다.


1. Framework Service 최적화 및 성능 개선

1.1 불필요한 서비스 로드 방지

사용자 정의 Framework Service는 부팅 시 불필요한 리소스를 소비하지 않도록 설계되어야 합니다. 다음과 같은 방법을 고려할 수 있습니다.

  • 지연 초기화(Delayed Initialization): 필요할 때만 서비스 인스턴스를 생성하도록 구현합니다.
  • Lazy Service Start: Broadcaster 또는 특정 이벤트가 발생할 때 서비스를 시작하도록 구성합니다.
  • Thread 또는 Handler를 사용한 작업 분배: 서비스 내에서 UI 스레드를 차단하지 않도록 백그라운드 스레드 활용을 고려합니다.
public class CustomService extends SystemService {
    private Handler mHandler;

    public CustomService(Context context) {
        super(context);
        mHandler = new Handler(Looper.getMainLooper());
    }

    @Override
    public void onStart() {
        mHandler.postDelayed(this::initializeService, 5000); // 서비스 시작을 지연
    }

    private void initializeService() {
        // 서비스 초기화 코드
    }
}

1.2 불필요한 CPU 및 메모리 사용 방지

  • 주기적인 타이머 및 반복적인 작업을 최소화합니다.
  • JobScheduler를 활용하여 백그라운드 작업을 최적화합니다.
  • 불필요한 로깅을 줄여 I/O 부하를 감소시킵니다.

2. Android SystemServer 부팅 시간 최적화

SystemServer의 부팅 시간은 Android 시스템의 전체적인 부팅 속도에 영향을 미칩니다. 다음과 같은 방법을 통해 부팅 시간을 단축할 수 있습니다.

2.1 서비스 초기화 최적화

  • 서비스 초기화를 지연하여 부팅 시 불필요한 로딩을 방지합니다.
  • Zygote Preloading을 통해 서비스에 필요한 클래스 및 리소스를 미리 로드하여 성능을 향상시킵니다.
SystemServer.java:
private void startOtherServices() {
    traceBeginAndSlog("StartCustomService");
    mSystemServiceManager.startService(CustomService.class);
    traceEnd();
}

2.2 Boot Timing 분석

  • logcat -b events를 활용하여 부팅 시간을 분석합니다.
  • dumpsys activity boot 명령어를 통해 각 서비스의 로딩 시간을 확인할 수 있습니다.
adb shell logcat -b events -s am_activity_launch_time
adb shell dumpsys activity boot

3. Binder Transaction 최적화

Binder는 Android의 주요 IPC(Inter-Process Communication) 메커니즘입니다. 성능을 최적화하지 않으면 과도한 트랜잭션 비용이 발생할 수 있습니다.

3.1 트랜잭션 비용 줄이기

  • Parcel 데이터 최소화: 불필요한 데이터를 전송하지 않도록 설계합니다.
  • 대량 데이터 전송 시 SharedMemory 활용: 대량 데이터를 IPC로 전달할 때는 ashmem을 사용하여 성능을 개선할 수 있습니다.
Parcel data = Parcel.obtain();
data.writeInt(42);
remote.transact(CUSTOM_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
data.recycle();

3.2 트랜잭션 분석

Binder 트랜잭션을 분석하려면 dumpsys binder를 활용할 수 있습니다.

adb shell dumpsys binder

4. ANR (Application Not Responding) 방지 기법

ANR은 UI 스레드가 장시간 응답하지 못할 때 발생합니다. 이를 방지하기 위한 주요 방법은 다음과 같습니다.

4.1 UI 스레드에서 블로킹 작업 제거

  • 네트워크 요청 및 데이터베이스 조회는 백그라운드 스레드에서 실행합니다.
  • AsyncTask 또는 HandlerThread를 활용합니다.
new Thread(() -> {
    performHeavyTask();
}).start();

4.2 트랜잭션 타임아웃 조정

  • binder_call_timeout_ms 설정을 활용하여 Binder 호출 시간을 조정합니다.
adb shell setprop debug.binder_call_timeout_ms 2000

5. Traceview, Systrace를 활용한 성능 분석

5.1 Traceview 활용

Traceview는 Java 메서드 실행 시간을 분석하는 도구입니다.

Debug.startMethodTracing("custom_service_trace");
// 실행할 코드
Debug.stopMethodTracing();

수집된 트레이스 파일은 traceview 명령어를 통해 분석할 수 있습니다.

adb pull /data/data/com.example.app/files/custom_service_trace.trace
traceview custom_service_trace.trace

5.2 Systrace 활용

Systrace는 시스템 전반적인 성능을 분석하는 도구입니다.

adb shell atrace --async_start gfx view sched
sleep 10
adb shell atrace --async_stop > trace.html

이후, trace.html을 웹 브라우저에서 열어 성능을 분석할 수 있습니다.


결론

Android 사용자 정의 Framework Service를 최적화하면 시스템 전체의 성능을 향상시키고, ANR 및 부팅 시간 지연을 방지할 수 있습니다. 이 글에서는 SystemServer 최적화, Binder 트랜잭션 비용 절감, ANR 방지 기법, 그리고 Traceview 및 Systrace를 활용한 성능 분석 방법을 소개했습니다.

각 기법을 적용하여 Android의 사용자 정의 Framework Service가 원활하게 동작하도록 최적화하시기 바랍니다.

728x90
반응형