Android Framework层整体执行流程高性能屏幕适配方案解析

应用场景:自定义View,APK加固,热修复,组件化,插件化,换肤,leakCanary,hilt,jetpack,glide,okhttp,rxjava...

Android系统初始化

2.1.png
2.2.png
2.3.png

上图最终到了WindowManager

2.4.png

进入绘制部分

2.5.png

屏幕适配怎么去做

public class UIUtils
    private Context context;

    //初始化时可以HOOK在contentprovider初始化时进行,leakcanary,bugly都是这么做的,放在Application初始化之前的

    //标准值
    private static final float STANDRD_WIDTH=1080F;
    private static final float STANDRD_HEIGHT=1920F;
    //实际值
    private static final float displayMetricsWidth;
    private static final float displayMetricsHeight;

    //简单单例
    private static UIUtils instance;
    public static UIUtils getInstance(Context context){
        if(instance == null){
            instance = new UIUtils(context);
        }
        return instance;
    }

    private UIUtils(Context context){
        this.context = context;
        WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics displayMetrics = new DisplayMetrics();

        if(displayMetricsWidth == 0.0f||displayMetricsHeight== 0.0f){
            windowManager.getDefaultDisplay().getMetrics(displayMetrics);
            //拿到状态栏高度
            int systemBarHeight = getSystemBarHeight(context);
            if(displayMetrics.widthPixels>displayMetrics.heightPixels){
                //横屏
                displayMetricsWidth ==displayMetricsHeight;
                displayMetricsHeight = displayMetrics.widthPixels-systemBarHeight;
            }else{
                //竖屏
                displayMetricsWidth ==(float)displayMetrics.widthPixels;
                displayMetricsHeight = displayMetrics.heightPixels-systemBarHeight;
            }
        }

    }

    private static final String DIME_CLASS="com.android.internal.R$dimen";
    //用于反射系统属性
    private int getSystemBarHeight(Context context){
        return getValue(context,DIME_CLASS,"system_bar_height",48);
    }
    private int getValue(Context context,String dimeClass,String system_bar_height,int i){
        try{
            Class clz = Class.forName(dimeClass);
            Object object = clz.newInstance();
            //反射属性
            Field field = clz.getField(system_bar_height);
            int id = Integer.parseInt(fidld.get(object).toString());
            return context.getResources().getDimensionPixelSize(id);
        }catch(Exception e){
            e.printStackTrace();
        }
        return i;
    }

    public float getHorValue(){
        return((float)displayMetricsWidth)/STANDRD_WIDTH;
    }
    public float getVerValue(){
        return((float)displayMetricsHeight)/(STANDRD_HEIGHT-getSystemBarHeight(context));
    }

自定义布局文件

public class ZxRelativeLayout extends RelativeLayout{
    public ZxRelativeLayout(Context context){super(context);}
    public ZxRelativeLayout(Context context,AttributeSet attrs){super(context,attrs);}
    public ZxRelativeLayout(Context context,AttributeSet attrs,int defStyleAttr){super(context,attrs,defStyleAttr);}
    public ZxRelativeLayout(Context context,AttributeSet attrs,int defStyleAttr,int defStyleRes){super(context,attrs,defStyleAttr,defStyleRes);}
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        float scaleX = UIUtils.getInstance(getContext()).getHorValue();
        float scaleY = UIUtils.getInstance(getContext()).getVerValue();
        int count = this.getChildCounr();
        for(int i=0;i

你可能感兴趣的:(Android Framework层整体执行流程高性能屏幕适配方案解析)