美文网首页
Android 运行时获得类的完全限定名

Android 运行时获得类的完全限定名

作者: GhostInMatrix | 来源:发表于2017-08-17 21:34 被阅读0次

最近有个需求是在push信息内制定某模块(Activty)名称,端上拿到该名称,在用户点击通知的时候自动打开对应Activity页面。
老逻辑是这样实现的:
每次新增一个功能模块的时候,都会在代码中使用switch语句进行选择判断:

    switch( nameFromPush){
        case "name1":
            startActivity(this,ActivityName1.class);
            break;
        case "name2":
            startActivity(this,ActivityName2.class);
            break;
        ...
        
    }

这么做有一个问题,需要修改代码。每次都要修改。
既然startActivity每次都要调用,且跳转的页面唯一取决于targetActivity的名称,那么,能否有一种方式能直接将push中的信息字段应用于startActivity()的第二个参数,从而废弃掉这种通过代码映射的方式呢。答案是肯定的,我们的思路即为下发targetActivity的类名,参数就可以直接使用。

但随之而来的又一个问题在于,类名其实是需要使用完全限定名的,也就需要推送下发全称,比如
startActivity(this,"com.ghostinmatrix.package1.TargetActivity.class");
,那么一旦这个模块修改了package(在类名本身不变的情况下),下发的push就不会生效了,因为app已经找不到这个类了。综上,push下发完全限定名是非常不合理的,只能下发类名。这就需要你在拿到push下发的“TargetActivity”,在app内生成它的完全限定名。我们可以使用如下方式:

DexFile df = new DexFile(DuApp.getAppContext().getPackageCodePath());
            Enumeration<String> enumeration = df.entries();
            while (enumeration.hasMoreElements()) {
                String classname = enumeration.nextElement();
                if (classname.contains("com.baidu.lbs")) {
                    String[] name = classname.split("\\.");
                    hashMap.put(name[name.length - 1], classname);
                }
            }

这里要介绍一下DexFile类,你只需要知道,通过ApplicationContext.getPackageCodePath能够访问到这个App内所有加载的类。而DexFile就是这样一个加载的入口。

    /**
     * Return the full path to this context's primary Android package.
     * The Android package is a ZIP file which contains application's
     * primary code and assets.
     *
     * <p>Note: this is not generally useful for applications, since they should
     * not be directly accessing the file system.
     *
     * @return String Path to the code and assets.
     */
    public abstract String getPackageCodePath();

注释大意为:返回这个context所对应的主包名,它是一个包含着app代码和资源的zip包。
因此通过这个路径可以获得所有主包名下的所有类的全限定名。

PS:对于Gradle 2.0.0以上的闪电编译(Instant Run)来说,存在一个问题,即通过上述方式不能获得apk中所有编译的类,而是只能找到其运行时和instant run所用到的.dex文件,(如com.tools.android.fd.runtime, com.tools.android.fd.common and com.tools.android.tools.ir.api)。其余的编译为.dex文件的类会被压缩到叫做instant-run.zip的压缩文件中放在同级目录下。不过不用担心,instant run只会用于Debug模式下的构建,而不会对Release模式有影响。

回到正题,DexFile能够得到所有类的完全限定名,也就一定会包含push下发的类名,后面的就不用多说了吧。找到对应的全限定名,作为第二个参数,startActivity。

相关文章

  • Android 运行时获得类的完全限定名

    最近有个需求是在push信息内制定某模块(Activty)名称,端上拿到该名称,在用户点击通知的时候自动打开对应A...

  • Java包范围可见性

    概述 本文主要介绍Java中的完全限定名,包范围可见性以及类从编译到运行时完全限定名的确定和类连接的大致过程。下面...

  • 类加载器

    类加载机制的基本过程 Java运行时,会根据类的完全限定名去寻找并加载类,负责加载类的类就是类加载器,它的输入是完...

  • JVM类加载机制

    JVM类加载机制 概述 类加载过程 加载 通过类的全限定名获取类的二进制流 将静态存储结构转化为方法区的运行时数据...

  • 反射的一些常规操作及简单的自定义注解

    获得Class类的四种方式1.调用运行时类本身的.class属性 2.通过运行时类的对象获取 3..通过Class...

  • java反射学习笔记(二)—— Class及Method等常用类

    [TOC] 1.Class 每个类运行时的类型信息就是用Class对象来表示的,它包含了与类有关的信息,获得运行时...

  • 运行时的简略介绍

    获得类(包括范畴类)或者协议类中的属性和变量列表 事例 查看所有的方法的返回值和参数类型 运行时调用方法 运行时解...

  • Java学习第15天

    完全限定名(qualified class name) - 使用类的时候,如果类名冲突了,可以加上它的包名加以区分...

  • Java类加载机制

    一:概述 1.加载:通过类的完全限定名(包名 + 类名)查找此类的class文件,并创建一个Class对象。2.验...

  • Android 6.0 运行时权限处理完全解析

    Android 6.0 运行时权限处理完全解析 http://blog.csdn.net/lmj623565791...

网友评论

      本文标题:Android 运行时获得类的完全限定名

      本文链接:https://www.haomeiwen.com/subject/wejnrxtx.html