Android开发利器之ActivityTracker
版权声明:本文为xing_star原创文章,转载请注明出处!
本文同步自
android开发利器之activitytracker
今天在群里面划水,有个小伙伴问到一个问题,”刚进公司 清单文件的activity 较多 不便于查找和定位,有什么办法解决”。这个问题我自认为还是很有经验的,向对方推荐了一个activitytracker软件,这个软件的作用嘛,就是开启了一个悬浮窗,会显示当前页面的activity的名称,无论是系统app,还是新接手的公司app,通过展示的activity类名,能够很容易的找到这块业务逻辑的代码所在。这个小工具真的很可以提高开发效率,所以准备记录下来,这个东西也是用了好几年了,不是今天有人问到,也不会有想法特意写篇文章记录下activitytracker。
源码分析
这个小工具在github上是开源的,地址是https://github.com/fashare2015/activitytracker,也有幸提过pr,代码量上就四五个类,很容易看懂的。本质上采用的是android的accessibilityservice这个辅助服务机制,时刻检测屏幕对应的activity,同时在service中用windowmanager显示悬浮view。
具体到代码层面,当用户开启辅助服务后,trackerservice被激活,onaccessibilityevent方法就会不断的被执行
@override public void onaccessibilityevent(accessibilityevent event) { log.d(tag, "onaccessibilityevent: " + event.getpackagename()); if (event.geteventtype() == accessibilityevent.type_window_state_changed) { charsequence packagename = event.getpackagename(); charsequence classname = event.getclassname(); if (!textutils.isempty(packagename) && !textutils.isempty(classname)) { eventbus.getdefault().post(new activitychangedevent( event.getpackagename().tostring(), event.getclassname().tostring() )); } } }
当onacessibilityevent被触发后,满足type_window_state_changed(用来表示window窗口发生了变化)条件后,通过eventbus将当前页面的包名,activity类名传递到floatingview中,接着就在floatingview中刷新对应的包名,类名值。
public void oneventmainthread(trackerservice.activitychangedevent event){ log.d(tag, "event:" + event.getpackagename() + ": " + event.getclassname()); string packagename = event.getpackagename(), classname = event.getclassname(); mtvpackagename.settext(packagename); mtvclassname.settext( classname.startswith(packagename)? classname.substring(packagename.length()): classname ); log.d(tag, "event:" + event.getpackagename() + ": " + event.getclassname() + ", end invoked!"); }
这块是核心逻辑。
floatingview是如何在service中显示隐藏的呢,可以看到trackerservice里面有个成员变量mtrackerwindowmanager,他用来控制显示隐藏floatingview。
trackerwindowmanager的静态代码块设置了悬浮view的默认显示位置,以及可以接受手势触摸
static { windowmanager.layoutparams params = new windowmanager.layoutparams(); params.x = 0; params.y = 0; params.width = windowmanager.layoutparams.wrap_content; params.height = windowmanager.layoutparams.wrap_content; params.gravity = gravity.left | gravity.top; params.type = windowmanager.layoutparams.type_phone; params.format = pixelformat.rgba_8888; params.flags = windowmanager.layoutparams.flag_not_touch_modal | windowmanager.layoutparams.flag_not_focusable; layout_params = params; }
public void addview() { if(mfloatingview == null){ mfloatingview = new floatingview(mcontext); mfloatingview.setlayoutparams(layout_params); mwindowmanager.addview(mfloatingview, layout_params); } }
addview方法就是将floatingview添加到service的windowmanager中,并显示出来,这块需要对windowmanager有所理解,了解其用法。
在我们真正使用的过程中会发现,activitytracker明明activity页面已经finish了,但是悬浮view依旧显示在当前的屏幕上,控制悬浮view显示的是windowmanager,而这个windowmanager在service中存活着。所以基本上就会一直显示着,很少会被系统杀死。
分析完后发现,这个小工具并不难,主要用到的就是accessibilityservice,windowmanager添加floatingview,以及eventbus。相信大家都可以实现这个小工具。
项目地址
推荐阅读