• 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

  • 相关阅读:
    0039. Combination Sum (M)
    imei和imsi
    APP网络测试要点和弱网模拟
    Git常用命令
    HTTP host头
    与apk签名有关的那些概念与命令
    你应该知道的运维术语
    nginx、fastCGI、php-fpm关系梳理
    adb连接手机报错解决方案汇总(win7)
    Android DVM
  • 原文地址:https://www.cnblogs.com/xing-star/p/10962004.html
Copyright © 2020-2023  润新知