天天看點

安卓如何更改系統全局視窗動畫背景廢話少說直接上代碼分析總結

安卓如何更改系統全局視窗動畫

  • 背景
  • 廢話少說直接上代碼
  • 分析
  • 總結

背景

 公司項目增加了個遠端控制的子產品,全套流程已經實作了,但是發現在用戶端網絡不穩定的情況下因為安卓的動畫原因會出現動畫幀卡頓在螢幕上留下殘影的問題,體驗不是很好,想到了關閉動畫減少畫面傳輸優化這一過程

廢話少說直接上代碼

/*
    * 反射IWindowManager實作控制系統動畫開關
    * 參考安卓開發者選項源碼:packages/apps/Settings/src/com/android/settings/DevelopmentSettings.java
    * */
    public static void hidenSystemAnim(boolean isClose) {
        try {
            Method getServiceMethod = Class.forName("android.os.ServiceManager").getDeclaredMethod("getService", new Class[]{String.class});
            Object ServiceManager = getServiceMethod.invoke(null, new Object[]{"window"});
            Class<?> cStub = Class.forName("android.view.IWindowManager$Stub");
            Method asInterface = cStub.getMethod("asInterface", IBinder.class);
            Object IWindowManager = asInterface.invoke(null, ServiceManager);
            //開關視窗動畫
            IWindowManager.getClass().getDeclaredMethod("setAnimationScale",new Class[]{int.class,float.class})
            	.invoke(IWindowManager,new Object[]{0,isClose?0f:1f});
            //開關過渡動畫
            IWindowManager.getClass().getDeclaredMethod("setAnimationScale",new Class[]{int.class,float.class})
            	.invoke(IWindowManager,new Object[]{1,isClose?0f:1f});
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
           

分析

1.通過閱讀:packages/apps/Settings/src/com/android/settings/DevelopmentSettings.java,打開會看到好多靜态變量,

安卓如何更改系統全局視窗動畫背景廢話少說直接上代碼分析總結

2.其中WINDOW_ANIMATION_SCALE_KEY,TRANSITION_ANIMATION_SCALE_KEY,為控制視窗動畫縮放,過渡動畫縮放的鍵

安卓如何更改系統全局視窗動畫背景廢話少說直接上代碼分析總結

3.繼續根據鍵值追查下去,可以發現在onCreate中鍵值被添加到了ListPreference并傳回給了mWindowAnimationScale

安卓如何更改系統全局視窗動畫背景廢話少說直接上代碼分析總結

4.跟蹤mWindowAnimationScale,最終在onPreferenceChange中發現參數傳遞給了writeAnimationScaleOption方法,根據不同的Preference類型判斷更改的對象

安卓如何更改系統全局視窗動畫背景廢話少說直接上代碼分析總結

5.writeAnimationScaleOption方法,我們主要看1,3參數,根據witch來确定需要更改設定的類型,根據newValue來設定新的參數值

安卓如何更改系統全局視窗動畫背景廢話少說直接上代碼分析總結

6.方法中調用了mWindowManager.setAnimationScale(which, scale);來設定新的參數值 mWindowManager 為AIDL對象,看看他的初始化過程,初始化過程的IWindowManager ServiceManager都是隐藏對象,使用反射機制擷取即可

安卓如何更改系統全局視窗動畫背景廢話少說直接上代碼分析總結

總結

1.小弟的第一篇部落格,寫的可能有點屎,望大家海涵……
2.以上過程為備用總結,如有不正還請諒解并指出,感謝。
           

繼續閱讀