Android开发利器之ActivityTracker

Android AUmaWSsSoi 9个月前 (06-01) 1570次浏览 0个评论
文章目录[隐藏]

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


java问与答 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:http://javaexception.com/archives/113
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址