-
잉여력 측정기 -개발(1/2)사이드 프로젝트 2017. 3. 26. 16:29
옛날 안드로이드 애플리케이션 개발 경험 상으로 요구 사항들을 구현하는 것이 별거 아닐 거라고 생각했는데... 왜 안드로이드는 시간이 흐르면서 계속 지원하지 않는 기능들이 많아지는 건지...! 스택 오버플로우에 있는 가이드 내용을 따라 가려고 하니 되는 것이 하나도 없고, 구현에 가장 핵심적인 API함수가 갑자기 depracated로 떠서 어떻게 구현해야 할 지 난감했었다. 다행히 깃허브에서 구해낸 소스와 여기저기 뒤져가면서 코드를 구현해 기획단계에서 만들어둔 요구사항들은 일단 구현을 해냈다. 이번 포스트에서는 개발과정에서 어떤 어려움이 있었고 어떻게 해결했는지를 정리해보려고 한다.
1. 실행되는 애플리케이션 목록 가져오기.
잉여력 측정기 애플리케이션 내에서 실행되고 있는 애플리케이션을 알아 낼 수 있어야 한다. 이 프로젝트를 시작하기 전에 현재 실행하고 있는 애플리케이션의 목록을 쭉 보여 줄 수 있는 안드로이드 API(ActivityManager 클래스에서 getRunningAppProcess()라는 함수를 사용하면 된다)가 있는 것을 알았었다. 이 함수를 이용해 쉽게 Application과 Service를 구별 할 수 있어서 별 다른 어려움 없이 구현 할 수 있을 줄 알았다.
https://developer.android.com/reference/android/app/ActivityManager.html 참조.
하지만 막상 위 함수를 사용하니 리턴된 애플리케이션 목록에 현재 설치한 애플리케이션 말고는 아무것도 보이지 않았다. 어떻게든 실행되고 있는 애플리케이션 목록을 보려고 다음도 실행하고 인스타그램도 실행 해봤는데 여전히 결과는 똑같았다... 알고 보니 시스템 애플리케이션이 아니면 함수를 호출한 애플리케이션 밖에 안보여준다고 한다... 보안상의 이유로 바꿨다는데 핵심적인 기능을 사용 할 수 없으니 대략 난감했다.
혹시나 애플리케이션 안에서 리눅스 'ps' 명령어를 사용 할 수 있을지 찾아봤다. 이걸로 실행되는 애플리케이션 목록을 얻어와서 여기서 애플리케이션의 실행 유무를 파악할 생각이었다. 다행이 깃허브 오픈소스중에서 "ps"와 동일한 역할 을 할 수 있도록 만들어뒀다.
(https://github.com/jaredrummler/AndroidProcesses)
프로세스 목록만 가져오는게 아니라 package 이름, pid, foreground 유무 등등을 가져와서 프로세스의 종류를 파악하는데 많은 도움이 됐다. 아마 이 프로젝트가 없었다면 나머지기능들을 만드는데 무지 애를 먹었을 것이다.
2. 애플리케이션 실행 횟수 카운팅하기.
애초의 내 계획은 스레드 하나를 돌리고 여기서 실행되는 프로세스를 주기적으로 관찰해 새로 생성된 프로세스를 보고 카운팅 하려고 했다. 하지만 이렇게 간단한 방식을 도입했더니 백그라운드 애플리케이션이 무지 많이 카운팅됐다(난 한번도 SSF Shop 애플리케이션을 실행 한 적이 없었는데 내 의지와 무관하게 가장 많이 사용한 애플리케이션이 됐다). 애플리케이션들마다 개발 할 때 서비스를 구현한 방식이 모두 달라서 실행하지 않으면 돌아가지 않는 앱이 있는 반면, 스마트폰 부팅과 동시에 실행되는 애플리케이션이 있었다. 이런 경우 '잉여력측정기'에서는 애플리케이션이 여러 번 실행 된 것으로 착각 할 수 있다.
또한 프로세스 생성 유무로만 판단 하다 보니 재실행 하는 경우(실행 된 앱 목록에서 눌러서 다시 실행시키는 경우)를 측정 할 수가 없었다. 사용자들이 애플리케이션을 종료하지 않고 다시 사용하는 경우도 있기 때문에 프로세스가 새로 생성되지 않아도 실행 횟수를 판단 할 수 있어야 한다.
예외 경우의 수들을 처리 하기 위해 나는 실행 횟수가 증가하는 경우를 크게 세가지로 분류 했다.
새로 생성된 프로세스: 스레드에서 관리하고있는 프로세스 목록 중에 존재하지 않는 프로세스가 생겨난 경우이다. 하지만 백그라운드 프로세스도 여러 번 반복해서 생겨날 수 있기 때문에 생겨난 프로세스가 Foreground인지 확인 한 후에 맞다면 실행 횟수를 증가 시키도록 한다.
- pid가 변화된 프로세스: 스레드가 관리하고 있는 프로세스 목록에는 있으나 pid가 변화된 경우이다. 이 경우는 사용자가 한 번 애플리케이션을 종료하고 난 후 다시 실행 한 경우이다. 새로 생성된 프로세스와 동일한 경우이며 동일하게 프로세스가 foreground에 있는지 유무로 실행 횟수를 증가시킨다.
- Background -> Foregrond 변화: 실행되고 있는 프로세스의 상태가 Background에서 Foreground로 변화한 상태이다. 이 경우는 애플리케이션을 종료하지 않고 다시 재실행한 경우를 처리한다.
세가지 경우에 대해서 만들어두니 백그라운드 애플리케이션이 카운팅되는 횟수가 눈에 띠게 줄었다. SSF Shop은 아예 없어졌고 기껏해야 KT 고객센터 정도... 이건 추가적으로 처리해야겠다.
(애플리케이션 카운팅 횟수 목록. 많이 실행된 순서로 정렬되어있다. 노래를 틀어놓고 개발해서 그런지 지니앱 실행 횟수가 가장 많다)
지금까지 나온 결과는 만족스럽다. 다른 기기에서도 동일하게 실행 된다면 현재의 알고리즘을 그대로 유지 할 수 있을 것 같다. 한 가지 걱정되는 점은 프로세스 목록을 보는 주기이다. 주기가 짧을 수록 카운팅 횟수의 정확도는 높아지고 주기가 길어질 수록 정확도는 낮아진다. 현재는 주기를 3초로 해두었는데 스마트매니저에서 배터리를 잡아먹는 애플리케이션이라고 뜬다.. 배터리 소모까지 생각하면 추가적으로 어떻게 구현해야 할 지 고민해봐야 겠다.
'사이드 프로젝트' 카테고리의 다른 글
잉여력측정기 -개발 중단 (0) 2017.04.24 잉여력 측정기 -개발(2/2) (0) 2017.03.30 잉여력 측정기 -기획 (0) 2017.03.26