Android dumpsys命令探究

Android dumpsys命令探究

1,在开发过程,我们经常需要dumpsys来获得相关信息,熟练掌握这个命令,能提高我们的调试效率。

2,直接在串口输入dumpsys会把系统的所有service(JAVA端)里面实现的  protected void dump(FileDescriptor fd, PrintWriter pw, String[] args)函数里面的所有内容都打印出来。但这不是我们需要的。后面接SERVICE参数,就只打印出我们自己感兴趣的系统服务里面的内容

3,如何找到自己感兴趣的参数的字符串?通过service list命令可以看到系统注册的所有service,如下:
  1. 10|root@U4:/ # service list
  2. Found 99 services:
  3. 0 subtitle_service: [com.droidlogic.SubTitleService.ISubTitleService]
  4. 1 imms: [com.android.internal.telephony.IMms]
  5. 2 media_projection: [android.media.projection.IMediaProjectionManager]
  6. 3 launcherapps: [android.content.pm.ILauncherApps]
  7. 4 fingerprint: [android.hardware.fingerprint.IFingerprintService]
  8. 5 trust: [android.app.trust.ITrustManager]
  9. 6 media_router: [android.media.IMediaRouterService]
  10. 7 hdmi_control: [android.hardware.hdmi.IHdmiControlService]
  11. 8 media_session: [android.media.session.ISessionManager]
  12. 9 restrictions: [android.content.IRestrictionsManager]
  13. 10 graphicsstats: [android.view.IGraphicsStats]
  14. 11 assetatlas: [android.view.IAssetAtlas]
  15. 12 dreams: [android.service.dreams.IDreamManager]
或者使用dumpsys -l也可以查看当前运行的service
比如,我需要看当前激活的窗口,是属于哪个应用。我们需要WindowManagerService里面一些信息。通过service lsit找到对应的名字为window。
  1. 55 window: [android.view.IWindowManager]
那么dumpsys window,内容如下:
  1. WINDOW MANAGER WINDOWS (dumpsys window windows)
  2. Window #2 Window{f02174b u0 KeyguardScrim}:
  3. mDisplayId=0 stackId=0 mSession=Session{45013c 3698:1000} mClient=android.view.ViewRootImpl$W@2dfb01a
  4. mOwnerUid=1000 mShowToOwnerOnly=false package=android appop=NONE
  5. mAttrs=WM.LayoutParams{(0,0)(fillxfill) sim=#10 ty=2029 fl=#1110900 pfl=0x1 fmt=-3 or=5 vsysui=0x3610000}
  6. Requested w=1920 h=1080 mLayoutSeq=16
  7. mHasSurface=false mShownFrame=[0.0,0.0][1920.0,1080.0] isReadyForDisplay()=false
  8. WindowStateAnimator{6fe9699 KeyguardScrim}:
  9. mLastFreezeDuration=+30s686ms
  10. Window #1 Window{b529a47 u0 com.stv.launcher/com.stv.launcher.activity.Launcher}:
  11. mDisplayId=0 stackId=0 mSession=Session{84a2ce5 11905:1000} mClient=android.os.BinderProxy@6fcb186
  12. mOwnerUid=1000 mShowToOwnerOnly=true package=com.stv.launcher appop=NONE
  13. mAttrs=WM.LayoutParams{(0,0)(fillxfill) sim=#32 ty=1 fl=#1810500 fmt=-3 wanim=0x1030001 needsMenuKey=2}
  14. Requested w=1920 h=1080 mLayoutSeq=180
  15. mHasSurface=true mShownFrame=[0.0,0.0][1920.0,1080.0] isReadyForDisplay()=true
  16. WindowStateAnimator{5b883e0 com.stv.launcher/com.stv.launcher.activity.Launcher}:
  17. Surface: shown=true layer=21005 alpha=1.0 rect=(0.0,0.0) 1920.0 x 1080.0
  18. Window #0 Window{9bcecfc u0 com.android.systemui.ImageWallpaper}:
  19. mDisplayId=0 stackId=0 mSession=Session{9e7fa1e 3832:u0a10013} mClient=android.os.BinderProxy@ba879ef
  20. mOwnerUid=10013 mShowToOwnerOnly=true package=com.android.systemui appop=NONE
  21. mAttrs=WM.LayoutParams{(0,0)(1920x1080) gr=#800033 ty=2013 fl=#318 fmt=2 wanim=0x10302f3}
  22. Requested w=1920 h=1080 mLayoutSeq=17
  23. mIsImWindow=false mIsWallpaper=true mIsFloatingLayer=true mWallpaperVisible=false
  24. mHasSurface=true mShownFrame=[0.0,0.0][1920.0,1080.0] isReadyForDisplay()=false
  25. WindowStateAnimator{c324de3 com.android.systemui.ImageWallpaper}:
  26. Surface: shown=false layer=21000 alpha=1.0 rect=(0.0,0.0) 1920.0 x 1080.0
  27. mLastFreezeDuration=+30s686ms
  28. mWallpaperX=0.5 mWallpaperY=0.5
  29. mCurConfiguration={1.0 ?mcc?mnc en_US ldltr sw720dp w1280dp h696dp 240dpi xlrg long land television -touch -keyb/v/h dpad/v s.6}
  30. mHasPermanentDpad=false
  31. mCurrentFocus=Window{b529a47 u0 com.stv.launcher/com.stv.launcher.activity.Launcher}
  32. mFocusedApp=AppWindowToken{7dfcc21 token=Token{9fe7a88 ActivityRecord{4a0d62b u0 com.stv.launcher/.activity.Launcher t1}}}
  33. mInTouchMode=false mLayoutSeq=180
  34. mLastDisplayFreezeDuration=+908ms due to Window{dde6531 u0 com.stv.globalsetting/com.stv.globalsetting.activity.UniversalActivity}
mFocusedApp就是我们需要的数据
内容太多?通过dumpsys window -h,可以看到更精简的用法。使用dumpsys window m即可
  1. root@U4:/ # dumpsys window -h
  2. Window manager dump options:
  3. [-a] [-h] [cmd] ...
  4. cmd may be one of:
  5. l[astanr]: last ANR information
  6. p[policy]: policy state
  7. a[animator]: animator state
  8. s[essions]: active sessions
  9. surfaces: active surfaces (debugging enabled only)
  10. d[isplays]: active display contents
  11. t[okens]: token list
  12. w[indows]: window list
  13. cmd may also be a NAME to dump windows. NAME may
  14. be a partial substring in a window name, a
  15. Window hex object identifier, or
  16. "all" for all windows, or
  17. "visible" for the visible windows.
  18. -a: include all available server state.
4,为什么说,window: [android.view.IWindowManager]就是对应的WidnowManagerService呢
这个“window”是SystemServer.java在初始化WindowServiceManager时添加到SystemManager的。
SystemServer.java
  1. Slog.i(TAG, "Window Manager");
  2. wm = WindowManagerService.main(context, inputManager,
  3. mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
  4. !mFirstBoot, mOnlyCore);
  5. ServiceManager.addService(Context.WINDOW_SERVICE, wm);
Context.WINDOW_SERVICE即为window
  1. public static final String WINDOW_SERVICE = "window";
5,如果想知道service里面的更多用法,就需要看各个Service里面的dump函数。
  1. else if ("-h".equals(opt)) {
  2. pw.println("Window manager dump options:");
  3. pw.println(" [-a] [-h] [cmd] ...");
  4. pw.println(" cmd may be one of:");
  5. pw.println(" l[astanr]: last ANR information");
  6. pw.println(" p[policy]: policy state");
  7. pw.println(" a[animator]: animator state");
  8. pw.println(" s[essions]: active sessions");
  9. pw.println(" surfaces: active surfaces (debugging enabled only)");
  10. pw.println(" d[isplays]: active display contents");
  11. pw.println(" t[okens]: token list");
  12. pw.println(" w[indows]: window list");
  13. pw.println(" cmd may also be a NAME to dump windows. NAME may");
  14. pw.println(" be a partial substring in a window name, a");
  15. pw.println(" Window hex object identifier, or");
  16. pw.println(" "all" for all windows, or");
  17. pw.println(" "visible" for the visible windows.");
  18. pw.println(" -a: include all available server state.");
  19. return;
  20. }
6,dumpsys是如何工作?
在dumpsys.cpp里面很简单的几个函数就可以通过参数传递,调到Java Serveice里面的dump函数
  1. sp<IServiceManager> sm = defaultServiceManager();
  2. ...
  3. int err = service->dump(STDOUT_FILENO, args);
7,有几个问题
7.1 dumpsys.cpp直接通过service调到Java里面dump函数,是一种从Native到Java层的调用
7.2 在Java Service里面dumpsys为啥是@override函数?父类是谁?而且跟参数有些不一样
  1. public void dump(FileDescriptor fd, PrintWriter pw, String[] args)
从Binder进程间通讯来看,从Native端来讲,任何一个Service都要继承BnInterface和IXXXX,而BnInterface继承自IBinder,在IBinder.h有定义dump函数,所以Service就是复写了IBinder的dump函数
IBinder.h
  1. virtual status_t dump(int fd, const Vector<String16>& args) = 0;
继承的类图如下:
上述是讲Native端是这样,Java端的Service也是这样吗?肯定也是这样,不信可以跟一下。以WindowManagerService为例
dump()函数重写,是重写Binder.java中的。
  1. /**
  2. * Print the object's state into the given stream.
  3. *
  4. * @param fd The raw file descriptor that the dump is being sent to.
  5. * @param fout The file to which you should dump your state. This will be
  6. * closed for you after you return.
  7. * @param args additional arguments to the dump request.
  8. */
  9. protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
  10. }
 另外,与IBinder.h中定义参数不一样,是因为dump函数就不一样。在Binder.java中
  1. /**
  2. * Implemented to call the more convenient version
  3. * {@link #dump(FileDescriptor, PrintWriter, String[])}.
  4. */
  5. public void dump(FileDescriptor fd, String[] args) {
  6. FileOutputStream fout = new FileOutputStream(fd);
  7. PrintWriter pw = new FastPrintWriter(fout);
  8. try {
  9. final String disabled;
  10. synchronized (Binder.class) {
  11. disabled = sDumpDisabled;
  12. }
  13. if (disabled == null) {
  14. try {
  15. dump(fd, pw, args); //最终调在这里,就到各个Java端的Service里面去了。
  16. }
  17. ...
  18. }
TOP