안드로이드를 개발하다보면 현재 시스템 상태에 대해서 궁금할 때가 있다. View Hierarchy라던지, 현재 Focus는 누가 가져갔는지 audio는 현재 누구한테 할당되어 있는지 등 이런 시스템 정보를 볼 수 있는 시스템 명령어가 dumpsys 이다. dumpsys를 통해 각 서비스들의 상태를 확인할 수 있다.
1. Adb Shell 접근하기
터미널에서 아래와 같이 명령어를 입력하면 usb에 연결되어 있는 디바이스 쉘로 들어갈 수 있다.
adb shell
단 여러 디바이스가 연결된 경우 다음과 같은 명령어를 사용하여 디바이스들을 확인하고
adb devices
List of devices attached
1c7aafe73b037bce device
973c6678 device
...
그중에 원하는 디바이스 ID로 아래와 같이 접근 가능
adb -s 973c6678 shell
2. 원하는 시스템 상태 확인하기
Activity 시스템 상태 확인하기
예를 들어 Activity의 시스템 상태를 확인하기 activity Service에서 해당 dump를 제공해주며 아래와 같이 사용할 수 있다.
//명령어
adb shell dumpsys activity ${packageName}
아래와 같이 현재 떠있는 activity나 fragment를 확인할 수 있고 View Hierarchy도 함께 확인 할 수 있다.
TASK com.kakao.talk id=595 userId=0
ACTIVITY com.kakao.talk/.activity.main.MainTabFragmentActivity 451df53 pid=23007
Local Activity b5337ad State:
mResumed=false mStopped=true mFinished=false
mChangingConfigurations=false
mCurrentConfig={0 1.1 themeSeq = 0 showBtnBg = 0 450mcc6mnc [ko_KR] ldltr sw411dp w411dp h773dp 420dpi nrml long hdr port finger -keyb/v/h -nav/h appBounds=Rect(0, 0 - 1080, 2094) s.45 mkbd/h desktop/d ?dc}
threadConfig={0 1.1 themeSeq = 0 showBtnBg = 0 450mcc6mnc [ko_KR] ldltr sw411dp w411dp h773dp 420dpi nrml long hdr port finger -keyb/v/h -nav/h appBounds=Rect(0, 0 - 1080, 2094) s.45 mkbd/h desktop/d ?dc} isDexCompatMode=false
mLoadersStarted=true
Active Fragments in 2fd1a78:
...
View Hierarchy:
DecorView@e88d633[MainTabFragmentActivity]
android.widget.LinearLayout{e3a58d V.E...... ......ID 0,0-1080,2094}
android.view.ViewStub{56ca342 G.E...... ......I. 0,0-0,0 #10201c4 android:id/action_mode_bar_stub}
android.widget.FrameLayout{bcf53 V.E...... ......ID 0,63-1080,2094}
androidx.appcompat.widget.FitWindowsLinearLayout{b64c090 V.E...... ......ID 0,0-1080,2031 #7f09001f app:id/action_bar_root}
androidx.appcompat.widget.ViewStubCompat{bf20d89 G.E...... ......I. 0,0-0,0 #7f09003b app:id/action_mode_bar_stub}
androidx.appcompat.widget.ContentFrameLayout{725b18e V.E...... ......ID 0,0-1080,2031 #1020002 android:id/content}
android.widget.RelativeLayout{8fa0daf V.E...... ......ID 0,0-1080,2031}
androidx.coordinatorlayout.widget.CoordinatorLayout{6fd55bc V.E...... ......ID 0,0-1080,2031}
com.kakao.talk.activity.main.MainTabAppBarLayout{bbf4fb4 V.E...... ......ID 0,0-1080,0}
com.kakao.talk.widget.theme.ThemeToolBar{564f945 G.E...... ......ID 0,0-0,0 #7f091401 app:id/toolbar}
com.kakao.talk.widget.theme.ThemeRelativeLayout{4f589a V.E...... ......I. 0,0-0,0 #7f09140d app:id/toolbar_main_container}
...
그외 시스템 상태 확인하기
dumpsys ${service}
위와 같이 dumpsys를 사용해서 서비스를 얻는 방법을 알아보았는데, 해당 서비스는 activity외에 어떤 것들이 있는지? 이런 것들은 어떻게 확인할 수 있는지 알아보자
해당 서비스에 들어갈 수 있는 이름들은 모두 context.java에 나열되어 있다.
context.java에서 스트럭쳐를 보면 아래와 같이 서비스 이름들이 상수로 들어간 것을 확인할 수 있는데
public static final String POWER_SERVICE = "power";
public static final String RECOVERY_SERVICE = "recovery";
public static final String SYSTEM_UPDATE_SERVICE = "system_update";
public static final String WINDOW_SERVICE = "window";
public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
public static final String ACCOUNT_SERVICE = "account";
public static final String ACTIVITY_SERVICE = "activity";
...
외에도 많은 서비스 이름들이 있다. ACTIVITY_SERVICE의 이름인 ‘activity’를 활용하여 해당 ACTIVITY_SERVICE 상태를 알 수 있었다.
나오는 결과를 모르겠어..
하지만 이렇게 보더라도 딱 보기에 알아볼 수 있는 메시지와 알아보기 어려운 메시지들이 있는데, 대체 이 메시지는 어떤걸 출력한거야? 라고 생각을 할 수 있다. 그럴 땐 해당 서비스의 dump라는 메서드를 확인해보면 된다. 예를 들어 audio Service에 dumpsys를 보면
MediaFocusControl dump time: 오후 3:49:21
Audio Focus stack entries (last is top of stack):
MultiFocusStack:
size:2
device:2
------------------------------
device = 0
...
으로 시작하는데, 이 내용은 AudioService.java에 dump 메서드에 있다.
//AudioService
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
mMediaFocusControl.dump(pw);
dumpStreamStates(pw);
dumpRingerMode(pw);
...
코드에서 ‘mMediaFocusControl’의 dump를 실행하는데 해당 메서드에서 audioService dumpsys의 맨 윗줄인 ‘MediaFocusControl dump time: 오후 3:49:21’를 출력하는걸 볼 수 있다.
protected void dump(PrintWriter pw) {
pw.println("\nMediaFocusControl dump time: "
+ DateFormat.getTimeInstance().format(new Date()));
dumpFocusStack(pw);
pw.println("\n");
// log
mEventLogger.dump(pw);
}
이렇게 모르는 메시지는 현재 어떤걸 출력하고 있는지 까지 확인할 수 있다.
결론..?
dumpsys는 주로 View Hierarchy를 확인하기 위해서 자주썼었는데, 최근엔 Tools에 LayoutInspector를 활용하면 볼 수 있기 때문에 (가끔 안되지만) 자주 사용할 일이 없지만, 대체 무슨 일인지 모르겠을 때 도움이 된다.