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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM