前语

本文首要包括以下内容
1.为什么需求ARouterARouter的基本原理
2.什么是APTARoutr注解是怎样收效的?
3.ARouter有什么缺开源阅览陷?
4.什么是字节码插桩,及怎样运用字节码插桩优化ARouter?

为什么需求ARouter

咱们知道,传统的Activity之间通讯,经过startActivity(intent),而在组件化的项目中,上层的module没有依托联系(即便两个module有依托联android下载装置系,也只能是单向的依托)
那么怎样结束在没有依托的情况下进行界面跳转呢?
ARoutr帮咱们结束了这点

运用ARouter的原因便是为了解耦,即没有依托时能够相互跳转

什么是APT

APTAnnotation Progradle装置装备cessing Tool的简称,即注解处理东西。
它是在编译期对代码中指定的注解进行解析,然后做一些其他处理(如经过javapoet生成新的Java文件)。
咱们常用的ButterKnife开源代码网站github,其原理便是经过注解处理器在编译期扫描代码中加入的@BindView@OnClick等注解进行扫描处理,然后生成XXX_ViewBinding类,结束了view的绑定。

ARouter中运用的注解处理器便是javapoet
(1)JavaPoet是square推出的开源java代码生成结构
(2)简练易懂的API,上手快
(3)让冗繁、重复的Java文件,主动化生成,进步工作效率,简化流程
(4) 相比原始APT方法,JavaPoet是OOP的

ARoutr开源代码网站github注解是怎样收效的?

咱们在运用ARouter时都会在Akotlin现在不火了ctivity上增加注解

@Route(path =开源节流是什么意思是什么 "/kotlin/test")
class Kotkotlin发音linTestActivity : Activity() {
...
}
@Route(path = "/kotlin/java")
public class TestNormalAcgradle依靠坐标怎样找tivity extends AppCompatActivity {
...
}

这些注解在编译时会被arouter-compiler处理,运用JavaPoet在编开源节流是什么意思是什么译期开源代码网站github生成开源众包类文件
生成的文件如下所示:

public class ARouter$$Group$$kotlin implements IRouteGroup {
@Oveandroid是什么手机牌子rride
public void loadInto(Map<String, RouteMeta> atlas) {
atlas.put("/kandroid手机otlin/jgradle装置装备ava", RouteMeta.build(RouteType.ACTIVITY, TestNormalActivity.class, "/kotlin/java", "kotlin", null, -1, -2147483648));
atlas.put("android体系/kotlin/test", RouteMeta.build(RouteType.ACTIVITY, KotlinTestActivity.class, "/kotlin/test", "kotlin", new ja源码共享网va.util.HashMap<String, Integer>(){{put("name", 8); put("age", 3); }}, -1, -2147483648));
}
}
public class ARouter$$Root$$modulekotlin implements IRouteRoot {
@Ovandroid下载erride
public void loadInto(Map<String, Class<? extends IRouteGroup>> routes) {
routes.put("kotkotlin发音lin", ARouter$$Group$$ko源码之家tlin.class);
}
}

如上所示,将注解的key与类的途径经过一个Map关联起来了kotlin现在不火了
只需咱们拿到这个Mapgradlew,即可在运行时经过注解的key拿到类kotlin现在不火了的途径,结束在不依android手机托的情况下跳转

怎样拿到这个Map呢?

ARouter缺点

ARouter的缺点就在于拿到这个Map的进程
开源们在运用ARouter时都需求初始化,ARouter所做的便是android手机在初始化时运用反射扫描指定包名下面的悉数className,然后再增加map
源码如下

public synchronized static void init(Context contkotlin怎样读ext, Thr源码编辑器编程猫下载eadPoolExecutor tp源码之家e) throws HandlerException {
//load by plugin first
loadRouterMap();
if (reg源码isterByPlugin) {
logger.info(TAG, "Load router开源是什么意思 map by arougradlewter-augradle装置装备to-register源码共享网 plugin.");
} else {
Set<String> routerMap;
// It will rebuild router map every times when debuggable.
if (A源码编辑器手机版下载Router.degradle依靠坐标怎样找buggable() || Pkotlin怎样读ackageUtils.isNewVersion(contextgradle翻译)) {
logger.info(TAG, "Run with debug mode or new install, rebuild router map.");
// These class was generated by arouter-compiler.源码编辑器编程猫下载
//反射扫描对应包Kotlin
rkotlin和javaogradle依靠坐标怎样找uterMap = ClassUtils.getFileNameByPackageName(mContext,源码年代 ROUTE_ROOT_PAKkotlin语法CAGEandroid的drawable类);
if (!route开源众包rMap源码超市.isEmpty()) {
//
context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).edit().putStringSet(gradle下载慢解决方法AROUTER_SP_KEY_MAP, routerMap).apply();
}
PackageUtils.updateVersion(context);    // Save new versionAndroid name when router map upda源码共享网te finisheskotlin和java.
} else {
logger.info(TAG, "Load router map from cache.");
routerM源码ap = new HashSet<>(context.gandroid/yunosetSharedPreferences(ARandroid/yunosOUTER_SP_CACandroid是什么手机牌子HE_KEY, Context.MODE_源码超市PRgradlewIVATE).getStr源码编辑器ingSet(AROUTER_SP_KEY_MAP, new Has开源阅览hSgradle教程et<String&gt开源节流;()));
}
...开源节流是什么意思是什么.
}
}

如上所示:
1.初度gradle翻开时会运用ClassUtils.getFileNameBy源码共享网PackageName来扫描对应包下的悉数className
2.在初度扫描后会存储在SharedPreferences中,这样后续就不需求再扫描了,这也是一个优化
3.以上两个进程都是耗时操作,就kotlin怎样读ARouter初度翻开时可能会构成慢gradle依靠坐标怎样找的原因
4.源码共享网那有没有方法源码编辑器手机版下载优化这个进程,让榜初度翻开也不需求扫描呢?

运用字节码插源码编辑器桩优化ARouter初度建议耗时

咱们再看看上面的代码

public synchronized static void init(Conte源码编程xt context, ThreadPoolExecutor tpe) throws HandlerExceptioandroid体系n {
//load by plug源码资本in first
loadRouterMaandroid是什么手机牌子p();
if (registerByPlugin) {
logger.info(TAG, "Load router map by aro开源是什么意思uter-auto-register plugin.");源码编程
} else {
....
}
}
private static voidandroid体系 loadRouterMap() {
//registergradle教程ByPlugin一向被置为false
registerByPlugin = false;
}

在初始化时,会在扫描之前,判别registerByPlugin,假设咱们需求的map现已被插件注册了,那也就不需求进行下面的耗时操作了
但是咱们能够看到在lo源码之家adandroid下载RouterMap中,registerByPlugin一向被设为false开源软件
regkotlin面试题isterByPluginkotlin发音是不是开源是什么意思一向没有收效?
这儿边其源码共享网有用到了字节码插桩来在loadRouterMap方法kotlin发音中刺进代码

什么是编译插开源桩?

断章取义,所谓编译插桩便是在代码编译期间批改已有的代码或许生成新代码。实际上,咱们项目中经常用到的 Dagger、ButterKnife 乃至是 Kotlin 言语,kotlin和java它们都用到了编译插桩的技术。
了解编译插桩之前,需求先回想一下Android项目中.java文件的编译开源进程:
【带着问题学】关于ARouter你应该知道的知识点
从上图能够看出,咱们能够在 1、2 两处对代码进行改造。
1.在.java文件编译成.class文件时,APTAndroidAngradle依靠坐标怎样找notation 等便是在此处android体系触发代码生成。
2.在.class文件进一android下载步优化成.dex文件时,也便是直接操作字节码文件,这便是字码码插桩

ARouter开源阅览app下载装置解生成用了榜首种方法,而建议优化则用了第二种方法
【带着问题学】关于ARouter你应该知道的知识点
ASM是一个十分健gradlew壮的字节码处理结构,基本上能够结束任何对字节码的操作,也便是自由度和开发的掌控度很高.
但是其相对来说比AspectJ上手难度要高,需求对Java字节码有必定了解.
不过ASM为咱们供给了拜访者方式kotlin和java来拜访字节码androidstudio装置教程文件,这种方式下能够比较简单的做一些字节码操作,结束一些功用。
一同android体系ASM能够准确的只注入咱们想要注入的代码,不会额外生成android平板电脑价格一些包装代码,所以性能上影响比较细小。

关于ASM运用的详细细节能够拜见:深化根究编译插桩技术(四、ASM 探秘)

字节码插桩对ARouter详细做了源码编辑器编程猫下载什么优化?

//源码代码,插桩前
private static void loa开源软件dRouterMap() {
//registerByPlugin一向被置为false
registerByPlugin = false;
}
/androidstudio装置教程/插桩后反编译代码
private static void loadandroid下载RouterMap() {
registerByPlugin = false;
register("com.alibaba.android.arouter.routes.ARouter$$Root$$modulejava");
register("com.gradle下载慢解决方法alibaba.android.arouter.routes.ARouter$$Root$$mogradle是什么dulekotlin");
registe开源矿工r("com.alibaba.android.arouter.routes.ARouter$$Root$$arouterapi");
register("gradle下载com.alibaba.android.arouter源码编辑器手机版下载.routes.ARouter$$Interceptors$$modulejava源码共享网");
regradle是干什么的gister("com.alibaba.android.arouter.routes.ARoutegradle教程r$$Providers$$mod源码编辑器编程猫下载ulejava");
registekotlin现在不火了r("com.alibaba.android.arouter.routes.A源码之家Router$$Providers$$modulekogradle下载慢解决方法tlin");
register("com.aligradle是什么baba.android.arouter.routes.ARouter$$Providers$$arouterapi");
}

1.插桩前源码与插桩后反编译代码如上所示
2.插桩后代码gradle即在编译期在loadRouterMap中刺进了register代码
3.经过这种方法即可防止在运行时经过反射扫描className,优化了建议速度

插件运用

运用Grandroid手机adle插件结束路由表的主动加载

apply plugi开源代码网站githubn: 'com.alibaba.arouter'
buildscript {
randroid的drawable类epositories {
jcenter()
}
depe源码共享网ndencies {
classpath "com.alibaba:arouter-register:?"
}
}android手机

1.可选运用,经过ARouter开源节流供给的源码编辑器注册插件进行路由表的主动加载
2.默许经过扫描dex的方法开源节流进行加载,经过gradle插件开源进行主动注册能够缩短初始化时间,一同解决运用加固源码资本导致无法直接拜访dex文件源码年代,初始化失利的问题
3.需求留神的是,该插件必须调配api 1.3.0以上版别运用!
4.ARouter插件基于AutoRegister进行开发,关于其原理的更多介绍可见:AutoRegister:一种更高效的组件主动注册计gradle下载慢解决方法

总结

本文首要叙说了
1.运用ARouter的底子原因是为在彼此不依托的情况下进行页面跳转以结束解藕
2.什么是APTARoutr注解生成的代码解析
3.ARouter的缺点在于初度初始化时会通源码过反射扫描dex,一同将作用存储在SP中,会拖慢初度建议速度
4.ARouter供给了插件结束在编译开源节流是什么意思是什么期结束路由表的主动加载,然后防止建议耗时,其原理是字节码插桩

参考资料

ARouter原理剖析及手动结束
ARouter疑难gradle下载慢解决方法杂症解析
加固后ARouter罢工了?看这儿
AutoRegister:一种更高效的组件主动注册计划