调试android源码之打堆栈加重写控件

来源:互联网 发布:mysql 5.7 for linux 编辑:程序博客网 时间:2024/05/26 15:57

转载:http://blog.csdn.net/aaa111/article/details/45627119


在跟一大神同时一起解bug的时候学到的。现在这个同事已经离职,祝他有更好的发展,也感谢他在带我解bug的时候教会我这么多知识。

通常我们在看android系统源码的时候需要查看一些方法的调用方,这时候在Android Studio中按快捷键Ctrl+Alt+H就好了(如何将Android系统源码导入到AS中请看我的前置文章)。但是很多时候一个方法会被很多地方调用,而我们又无法确定我们需要追的流程走的是哪一条路线的时候就,打印堆栈就是一个很好的方法。 
一个简单的使用方法如下:

打堆栈

比我们知道这个方法会被执行,但是我们不知道这个方法是被谁调用执行的,那我们可以在这个方法里添加下面几行代码:

 try {      throw new Exception("debug: enabled" + enabled/*可以加上你需要的参数信息*/);  } catch (Exception e) {      e.printStackTrace();  }
  • 1
  • 2
  • 3
  • 4
  • 5

一般这个时候从log中就可以看到调用的流程。我这里没有现成的log就不举例了。

重写控件

还有一种情况,我们甚至不知道这个方法会不会执行的时候,并且我们关注的重点其实是一个控件会不会被显示出来,那么我们可以以直接去重写这个控件,然后在重写这个控件的时候添加上打印堆栈的代码:

  1. 重写这个控件 
    比如我们现在需要查看一个ImageButton是什么时候显示出来的,被谁调用显示出来的,那么可以先写一个MyImageButton.java类,在其中重写相应的方法,并天机打堆栈的代码。 
    java代码中:
    public class MyImageButton extends ImageButton {         public MyImageButton(Context context, AttributeSet attrs) {             super(context, attrs);         }         @Override         public void setVisibility(int visibility) {             super.setVisibility(visibility);             try {                 throw new Exception("cktdebug: enabled" +  visibility);             } catch (Exception e) {                 e.printStackTrace();             }         }     }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  1. 使用这个控件的.xml文件中 使用我们重写的这个控件 
    将原先使用到ImageButton的地方
    <ImageButton        android:id="@+id/eggplant"        android:layout_width="wrap_content"        android:layout_height="wrap_content"/>
  • 1
  • 2
  • 3
  • 4

改写成

    <com.example.hcz.smartmenu.MyImageButton        android:id="@+id/eggplant"        android:layout_width="wrap_content"        android:layout_height="wrap_content"/>
  • 1
  • 2
  • 3
  • 4

搞定。 
这样在需要显示这个ImageButton的时候,就会使用我们的重写的MyImageButton,并且在显示的时候执行了重写的setVisibility方法,自然机会打印堆栈,从堆栈中得到了我们想要的信息,即在哪里调用方法显示出了这个ImageButton。


原创粉丝点击