본문 바로가기
Android

[깡샘의 안드로이드 프로그래밍] 정리 22 - ActivityManager

by 들풀민들레 2018. 1. 6.

 

 

 

본 글은 [깡샘의 안드로이드 프로그래밍 - 루비페이퍼] 의 내용을 발췌한 것입니다.
좀더 자세한 내용은 책을 통해 확인해 주세요.

 

 

 

 

 

 

 

20장. 서비스 컴포넌트

 

20.4.1. ActivityManager

 

ActivityManager는 앱의 실행 상태와 관련된 다양한 정보를 획득할 목적으로 사용되는 시스템 서비스입니다. 시스템에 실행되고 있는 서비스 목록, 앱의 액티비티가 화면의 상단을 차지하고 있는지에 대한 정보 등을 획득할 목적으로 사용됩니다. 특히, 서비스를 이용할 때는 ActivityManager를 많이 사용합니다.

 

구동 중인 서비스 목록 획득

 

시스템에서 실행 중인 서비스 목록을 확인해야 할 때가 있습니다. 서비스는 장시간 백그라운드에서 업무를 진행할 목적으로 사용되지만, 시스템이나 사용자가 서비스를 종료할 수 있습니다. 따라서 장시간 수행되는 서비스는 실행되고 있는지를 판단해서 만약 실행되고 있지 않다면 다시 실행해 주어야 합니다.

 

예를 들어, 카카오톡 같은 채팅 프로그램을 만든다고 가정해 봅시다. 채팅 프로그램은 서비스에서 서버에 접속하여 데이터 통신을 해야 합니다. 이 서비스는 일반적으로 시스템의 부팅이 완료되는 시점에 실행됩니다. 하지만 잘 실행되던 서비스가 사용자나 시스템에 의해 종료된다면 채팅 업무를 진행할 수 없습니다. 결국, 지속적으로 서비스의 실행 상태를 체크해서 실행되고 있지 않다면 다시 실행해 주어야 합니다.

 

ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

List<ActivityManager.RunningServiceInfo> list = am.getRunningServices(100);

for(ActivityManager.RunningServiceInfo info : list) {

String className=info.service.getClassName();

String packageName=info.service.getPackageName();

//...

}

 

시스템 서비스는 startService ( ) 함수로 실행되는 게 아니라, getSystemService ( ) 함수를 이용합니다. getSystemService ( ) 함수의 매개변수에 문자열 상수를 대입하고 이 값으로 식별되는 시스템 서비스를 획득하여 이용하는 구조입니다. 이렇게 획득한 ActivityManager의

getRunningServices ( ) 함수를 이용하여 현재 시스템에서 동작 중인 모든 서비스 목록을 얻을 수 있습니다. getRunningServices ( ) 함수의 매개변수에 max 값을 100으로 설정하면 최대 100개까지 정보를 가져옵니다. 결괏값은 각 서비스의 정보가 RunningServiceInfo 타입의 객체로 반환됩니다.

이렇게 얻은 RunningServiceInfo를 이용해 실행 중인 Service의 클래스명, 앱의 패키지명 등으로 우리 앱의 서비스가 구동 중인지 판단할 수 있습니다.

 

최상위 액티비티 판단

 

서비스를 이용할 때 경우 ActivityManager의 사용자 화면을 점유한 액티비티 정보도 자주 이용됩니다. 서비스의 특정 데이터를 사용자에게

화면으로 알려야 할 때가 있습니다. 이 역시도 채팅 프로그램이 대표적인 예입니다. 사용자 화면에 데이터를 출력할 액티비티가 나오고 있을

때는 액티비티에 직접 데이터를 전달하면 되지만, 사용자가 그 액티비티를 화면 상단에 출력하고 있지 않을 수도 있습니다. 이때는 사용자 행동을 방해하지 않기 위해 알림으로 알려 주는 게 일반적입니다. 이를 구현하려면 사용자 화면을 점유하고 있는 액티비티 정보를 구해야 합니다.

 

 

 

다음은 ActivityManager의 getRunningTasks ( ) 함수를 이용하여 최상위 액티비티를 판단하는 코드입니다.

 

ActivityManager manager = (ActivityManager) getSystemService( Activity.ACTIVITY_SERVICE );

//api level 21.. deprecated..

List<ActivityManager.RunningTaskInfo> list = manager.getRunningTasks(1);

ActivityManager.RunningTaskInfo info=list.get(0);

if(info.topActivity.getClassName().equals("com.example.test7_20.Lab4Activity")){

//...

}else {

//...

}

 

getRunningTasks ( ) 함수를 이용하면 실행 중인 액티비티 정보가 담긴 RunningTaskInfo 객체를 얻을 수 있습니다. RunningTaskInfo 객체에서 최상위 액티비티의 클래스명은 topActivity.getClassName( ) 함수로 구할 수 있으며, 이 문자열을 비교하여 특정 액티비티가 화면을 점유하고 있는지 판단하게 됩니다. getRunningTasks ( ) 함수는 API Level 21(Android 5.0)부터 deprecated 되긴 했지만, 하위 호환성을 목적으로 계속 사용할 수 있습니다. 또한, 앱의 Task 정보를 구하려면 퍼미션이 부여되어 있어야 합니다.

 

<uses-permission android:name="android.permission.GET_TASKS"/>

 

AndroidManifest.xml 파일에 android.permission.GET_TASKS 이름의 퍼미션이 설정되어야 하는데, 이 이름의 퍼미션도 API Level 21 (Android 5.0)부터는 추가하지 않아도 됩니다. 다른 이름으로 대체하는 게 아니라 아예 선언하지 않아도 상관없습니다. 하지만 앱이 21 하위 버전에서도 동작한다면 이 퍼미션이 선언되어 있지 않으면 실행 시 에러가 발생합니다.