Android开发利器之ActivityTracker
版权声明:本文为xing_star原创文章,转载请注明出处!
本文同步自http://javaexception.com/archives/113
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。相信大家都可以实现这个小工具。
项目地址
https://github.com/fashare2015/ActivityTracker
Android开发利器之ActivityTracker的更多相关文章
- Android开发利器之Data Binding Compiler V2 —— 搭建Android MVVM完全体的基础
原创声明: 该文章为原创文章,未经博主同意严禁转载. 前言: Android常用的架构有:MVC.MVP.MVVM,而MVVM是唯一一个官方提供支持组件的架构,我们可以通过Android lifecy ...
- Android开发利器之pidcat
介绍pidcat: pidcat 是Android届JakeWharton大神开发的一款命令行工具,堪称Android开发利器,它能方便Android程序猿捕获日志,过滤日志,定位程序问题,超级好用. ...
- Android开发利器之stetho
文章同步自javaexception Stetho是什么? github上地址https://github.com/facebook/stetho stetho是facebook出品的一款开发调试工具 ...
- 那些年一起用过的iOS开发利器之Parse
阅读此文章需要对Objective-C和iOS有一定的了解,完全没有基础的朋友请先阅读<让不懂编程的人爱上iPhone开发>系列教程. 什么是后台服务(back-end service)? ...
- 那些年一起用过的iOS开发利器之CocoaPods
本系列所有工具的简介见:http://www.cnblogs.com/lloydsheng/p/3637606.html CocoaPods是一个负责管理iOS项目中第三方开源代码的工具.CocoaP ...
- 后端系统开发利器之gflags
gflags是Google的一个开源项目,用于解析程序运行参数.gflags简单易用,它的好处在于统一配置格式,减少开发工作量.在工程实践中,gflags在简化开发和测试方面表现非常出色,它还有一个很 ...
- ionic2——开发利器之Visual Studio Code 常用快捷键
主命令框 F1 或 Ctrl+Shift+P: 打开命令面板.在打开的输入框内,可以输入任何命令,例如: 按一下 Backspace 会进入到 Ctrl+P 模式 在 Ctrl+P 下输入 > ...
- 那些年一起用过的iOS开发利器之Code Pilot
本系列所有工具的简介见:http://www.cnblogs.com/lloydsheng/p/3637606.html 什么是Code Pilot? Code Pilot是一个Xcode的扩充套件, ...
- Python开发利器之UliPad
一.安装Ulipad 因为ulipad编辑器使用的是wxpython编写的gui,所以我们需要第三方库wxpython的支持,先讲一下Ulipad在Windows系统环境下的安装: 1. 确实自己的w ...
随机推荐
- 2.Linux的用户、用户组、权限、文件系统管理及其网络配置
2.1 Linux的用户及用户组 2.1.1 Linux的用户管理 用户账号管理包含以下三个方面: 用户账号的添加.删除.与修改 用户口令(密码)的管理 用户组的添加.删除管理 Linux系统中用户信 ...
- 从0开始复习JS---1、函数复习
1. 写一个函数,实现对数字数组的排序. function get_order(array){ for(var i = 0; i <array.length-1; i++){ for(var j ...
- Scrapy实战:爬取http://quotes.toscrape.com网站数据
需要学习的地方: 1.Scrapy框架流程梳理,各文件的用途等 2.在Scrapy框架中使用MongoDB数据库存储数据 3.提取下一页链接,回调自身函数再次获取数据 重点:从当前页获取下一页的链接, ...
- python爬虫10 | 网站维护人员:真的求求你们了,不要再来爬取了!!
今天 小帅b想给大家讲一个小明的小故事 ... 话说 在很久很久以前 小明不小心发现了一个叫做 学习python的正确姿势 的公众号 从此一发不可收拾 看到什么网站都想爬取 有一天 小明发现了一个小黄 ...
- Python类中的 私有变量和私有方法
默认情况下,Python中的成员函数和成员变量都是公开的(public),在python中没有类似public,private等关键词来修饰成员函数和成员变量.在python中定义私有变量只需要在变量 ...
- 并发通信Manage,队列, 互斥锁
目录 Manage 队列 先入先出 互斥锁 Manage 进程间的通信是被限制的 from multiprocessing import Process a = 1 def func(): glob ...
- 详解Cookie、LocalStorage、SessionStorage
不管是笔试还是面试相信大家都会经常遇到问Cookie.LocalStorage.SessionStorage 这三个不同的,什么不说先上一波图先: 针对他们大小之分应用场景也有不同: 因为考虑到每个 ...
- map put
public class test { static Map<String, Map<String, Integer>> mapB = new HashMap<Strin ...
- PatentTips - Indexes of graphics processing objects in GPU commands
BACKGROUND A graphics processing unit (GPU) is a specialized electronic device that is specifically ...
- F2BPM中关于工作流引擎驳回设计
1.1 关于驳回 驳回,在有的应用中叫“回退”.驳回是中国特色的一种方式,驳回在流程图上也没有迁移线的表达经常也是隐性的,比如申请经费可能由于资料不足被驳回来补充资料,像这样的例子有非常多,也很常见. ...