BasicLibrary架构设计旅程(一)—Android必备技

2022-12-04  本文已影响0人  Peakmain

前言

阅读源码的能力

为什么需要具有阅读源码的能力呢?

当我们通过百度搜索视频,博客,stackOverflow找不到我们问题解决办法的时候,可以通过阅读源码来寻找问题,并解决问题,如以下两个案例

一、AppBarLayout阴影问题

findViewById<AppBarLayout>(R.id.navigation_header_container).elevation=0f

运行之后,发现阴影还仍然存在

  static void setDefaultAppBarLayoutStateListAnimator(
      @NonNull final View view, final float elevation) {
    final int dur = view.getResources().getInteger(R.integer.app_bar_elevation_anim_duration);

    final StateListAnimator sla = new StateListAnimator();

    // Enabled and liftable, but not lifted means not elevated
    sla.addState(
        new int[] {android.R.attr.state_enabled, R.attr.state_liftable, -R.attr.state_lifted},
        ObjectAnimator.ofFloat(view, "elevation", 0f).setDuration(dur));

    // Default enabled state
    sla.addState(
        new int[] {android.R.attr.state_enabled},
        ObjectAnimator.ofFloat(view, "elevation", elevation).setDuration(dur));

    // Disabled state
    sla.addState(new int[0], ObjectAnimator.ofFloat(view, "elevation", 0).setDuration(0));

    view.setStateListAnimator(sla);
  }
image.png

二、Glide加载图片读取设备型号问题

小总结

阅读字节码的能力的重要性

当我们熟练掌握字节码能力,我们能够深入了解JVM,通过ASM实现一套埋点+拦截第三方频繁调用隐私方法的问题

字节码基础知识

局部变量表

操作数栈

一些常用的助记符

i++和++i区别
public class Test {

    public static void main(String[] args) {
       int i=10;
       int a=i++;
       int j=10;
       int b=++j;
        System.out.println(i);
        System.out.println(a);
        System.out.println(j);
        System.out.println(b);
    }
}

字节码结果分析

 0 bipush 10
 2 istore_1
 3 iload_1
 4 iinc 1 by 1
 7 istore_2
 8 bipush 10
10 istore_3
11 iinc 3 by 1
14 iload_3
15 istore 4
17 getstatic #2 <java/lang/System.out : Ljava/io/PrintStream;>
20 iload_1
21 invokevirtual #3 <java/io/PrintStream.println : (I)V>
24 getstatic #2 <java/lang/System.out : Ljava/io/PrintStream;>
27 iload_2
28 invokevirtual #3 <java/io/PrintStream.println : (I)V>
31 getstatic #2 <java/lang/System.out : Ljava/io/PrintStream;>
34 iload_3
35 invokevirtual #3 <java/io/PrintStream.println : (I)V>
38 getstatic #2 <java/lang/System.out : Ljava/io/PrintStream;>
41 iload 4
43 invokevirtual #3 <java/io/PrintStream.println : (I)V>
46 return
ASM 解决隐私方法问题

怀疑的态度

kotlin object实现的单例类是懒汉式还是饿汉式
image.png
image.png
object Test {
    const val TAG="test"
}

通过工具看下反编译后的代码


image.png
image.png

static代码块什么时候初始化呢?

单例的懒汉式和饿汉式的区别是什么呢

public class Test {
    private static Test mInstance;
    static {
        System.out.println("static:"+mInstance);
    }
    private Test() {
        System.out.println("init:"+mInstance);
    }
    public static Test getInstance() {
        if (mInstance == null) {
            mInstance = new Test();
        }
        return mInstance;
    }
    public static void main(String[] args) {
        Test.getInstance();
    }
}
public class Test1 {
    private static final Test1 mInstance=new Test1();

    private Test1(){
        System.out.println("init:"+mInstance);
    }
    static {
        System.out.println("static:"+mInstance);
    }
    public static Test1 getInstance(){
        return mInstance;
    }

    public static void main(String[] args) {
        Test1.getInstance();
    }
}

我们现在回到kotlin的object,我们将其转成Java类

public class Test2 {
    public static final String TAG = "test";
    private Test2() {
        System.out.println("init:" + mInstance);
    }
    public static Test2 mInstance;
    static {
        Test2 test2 = new Test2();
        mInstance = test2;
        System.out.println("static:" + mInstance);
    }

    public static void main(String[] args) {
        System.out.println(Test2.TAG);
    }
}

总结

上一篇下一篇

猜你喜欢

热点阅读