Android 组件化和插件化详解

2022-11-16  本文已影响0人  Luke_单车

1. Android 组件化

ARouter 核心实现思路是,我们在代码里加入的 @Route 注解,会在编译时期通 过 apt生成一些存储 pathactivityClass映射关系的类文件,然后 app进程启动的时候会拿到这些类文件,把保存这些映射关系的数据读到内存里(保存在 map 里),然后在进行路由跳转的时候,通过 build() 方法传入要到达页面的路由 地址,ARouter会通过它自己存储的路由表找到路由地址对应的 Activity.class(activity.class = map.get(path)),然后 new Intent(),当调用 ARouterwithString()方法它的内部会调用 intent.putExtra(String name, String value), 调用 navigation()方法,它的内部会调用startActivity(intent)进行跳转,这样便可 以实现两个相互没有依赖的 module顺利的启动对方的 Activity.

3.1 ARouter的原理就是所有的moudle都引用ARouter,然后再moudle中去生成一个映射表,然后再把这个映射表传到ARouter
3.2 映射表生成 , 我们一般配置ARouter会这样写

@Route(path = xxx/xxx)
public class xxx{
    ......
  }

3.3 发起跳转

ARouter.getInstance().build("/user/UserMainActivity").navigation()

ARouter的代码要简洁很多,完全不需要手动注册路由就可完成跳转,它是怎么做到的呢?
3.4 很神奇!与前篇我们实现的路由相比,ARouter的代码要简洁很多,完全不需要手动注册路由就可完成跳转,它是怎么做到的呢?
通过跟进navigation()函数调用过程,我们把目光聚焦到两个容器中:

  // ARouter源码
class Warehouse {
    // Cache route and metas
    //用于存储所有的路由组
    static Map<String, Class<? extends IRouteGroup>> groupsIndex = new HashMap<>();
    //用于存储已注册的所有路由
    static Map<String, RouteMeta> routes = new HashMap<>();  
  
    ...
}

public interface IRouteGroup {
    /**
     * Fill the atlas with routes in group.
     * atlas用于存储当前组里的所有路由,实际传入的就是Warehouse.routes
     */
    void loadInto(Map<String, RouteMeta> atlas);
}
 // 路由包装类,路由目标的Class对象就存储在这里面
public class RouteMeta {
    private RouteType type;         // Type of route
    private Element rawType;        // Raw type of route
    private Class<?> destination;   // Destination
    private String path;            // Path of route
    private String group;           // Group of route
    private int priority = -1;      // The smaller the number, the higher the priority
    private int extra;              // Extra data
    private Map<String, Integer> paramsType;  // Param type
    private String name;
    
    ...
}
// group可省略不写
@Route(path = "/user/UserMainActivity")
class UserMainActivity : AppCompatActivity() {
      ...
}

分析这两个容器的作用,大致如下:
1、当传入path进行跳转时,优先从Warehouse.routes中直接获取路由对象;
2、路由对象不存在,就需要通过Warehouse.groupsIndex路由组来完成注册功能
3、注册成功后,当前path所在组的所有路由都将存储到Warehouse.routes中;
4、回到第1步,获取路由对象;
5、读取路由对象信息;
6、完成跳转

2. Android 插件化

public class PathClassLoader extends BaseDexClassLoader {
    public PathClassLoader(String dexPath, ClassLoader parent) {
        super(dexPath, null, null, parent);
    }

    public PathClassLoader(String dexPath, String libraryPath,
            ClassLoader parent) {
        super(dexPath, null, libraryPath, parent);
    }
}
public class DexClassLoader extends BaseDexClassLoader {
    public DexClassLoader(String dexPath, String optimizedDirectory,
            String libraryPath, ClassLoader parent) {
        super(dexPath, new File(optimizedDirectory), libraryPath, parent);
    }
}

插件化中一般使用的是 DexClassLoader

3. 组件化和插件化的区别 ?

  1. 组件化 : 是将一个App分成多个模块,每个模块都是一个组件(module),开发过程中可以让这些组件相互依赖或独立编译、调试部分组件,但是这些组件最终会合并成一个完整的Apk去发布到应用市场。
  2. 插件化 : 是将整个App拆分成很多模块,每个模块都是一个Apk(组件化的每个模块是一个lib),最终打包的时候将宿主Apk和插件Apk分开打包,只需发布宿主Apk到应用市场,插件Apk通过动态按需下发到宿主Apk
上一篇 下一篇

猜你喜欢

热点阅读