搜索
您的当前位置:首页正文

关于stub、@hide那点事儿

来源:哗拓教育

stub包

若干年前,我用eclipse开发安卓,反编译jar的时候发现android.jar内部的东西,所有方法都只有一个实现:

throw new RuntimeException("Stub!");

当时我还只会写几个activity,完全是懵逼状态,这样的实现到底能干什么?
后来查阅了一系列资料,明白了这个jar只是用于编译的,程序打包成apk的时候并不会把这个jar打进去,而编译时只需要类结构并不需要管里面的实现,当然,我们并不会去在电脑上实际运行它。
那么到了实际运行时这些类是如何获取的呢?我觉得,真正具有完整实现的android.jar里面的东西当然在安卓设备里,让我们验证一下:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ClassLoader classLoader = getClass().getClassLoader();
        while (classLoader != null){
            Log.e("classloader",classLoader.getClass().getName());
            classLoader = classLoader.getParent();
        }
        try {
            Class activityThreadClass = Class.forName("android.app.ActivityThread");
            Log.e("classloader",String.format("ActivityThread is loaded by %s", activityThreadClass.getClassLoader()));
            Log.e("classloader",String.format("Handler is loaded by %s", Handler.class.getClassLoader()));
            Log.e("classloader",String.format("MainActivity is loaded by %s", getClass().getClassLoader()));
            Log.e("classloader",String.format("Application is loaded by %s", getApplication().getClass().getClassLoader()));
            Log.e("classloader",String.format("CommonTabLayout is loaded by %s", CommonTabLayout.class.getClassLoader()));

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

以上代码,先循环取父加载器,看系统中有几种java类加载器,然后分别取了我们自定义的类、第三方库的类、系统类进行输入看是哪种类加载器加载的它。输出结果如下:


输出结果

可以看到,系统类是由BootClassLoader预先加载的,第三方库的类(打到了apk包里)和我们自定义的类(也在apk里)是由PathClassLoader加载的。当然,类加载器在jni层还有其他的,我们用java代码访问不到而已。
我们程序在用到系统类的时候,根据类加载器的双亲委派模式,向上查找,由BootClassLoader返回预先加载的类供我们使用,这里的类已经不是stub实现的假类了。

无法查看的类

本文如未解决您的问题请添加抖音号:51dongshi(抖音搜索懂视),直接咨询即可。

热门图文

Top