Android 組件化開發(fā)

一 gradle語法

Gradle環(huán)境

1.Android studio配置

?????? classpath'com.android.tools.build:gradle:3.5.0'

2.Gradle配置

?????? distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip

什么是Gradle?

首先Gradle是一種構(gòu)建工具,它的出現(xiàn)讓工程有無限可能

Gradle核心是基于Groovy腳本語言,Groovy腳本基于Java且拓展了Java,因此Gradle需要依賴JDK和Groovy庫

?和ant、maven構(gòu)建有區(qū)別评架,gradle是一種編程思想

如何配置公共Gradle

????配置公共Gradle的作用:

? ????? 1.區(qū)別生產(chǎn)環(huán)境和測試環(huán)境

? ????? 2.抽離Android信息君丁,便于統(tǒng)一管理

? ????? 3.統(tǒng)一管理依賴的包

????步驟

? ? ? ? 1.在build.gradle同級目錄下新建一個gradle文件

? ? ? ? 2.通過ext代碼塊添加字典

ext {

username ="sunjchao"

? ? //生產(chǎn)/開發(fā)環(huán)境

? ? isRelease =true

? ? //gradle共用配置睛蛛,建立map存儲,對象名文判,key都可以自定義过椎,groovy糖果語法,非常靈活

? ? androidId = [

compileSdkVersion:29,

buildToolsVersion:"29.0.2",

minSdkVersion? ? :23,

targetSdkVersion :29,

versionCode? ? ? :1,

versionName? ? ? :"1.0"

? ? ]

appId = [

app? ? :"com.example.myapplication",

library:"com.example.library"

? ? ]

url = [

debug? :"debug",

release:"release"

? ? ]

supportLibrary ="28.0.0"

? ? dependencies = [

"appcomppat":"androidx.appcompat:appcompat:1.1.0",

"recycleview":"com.android.support:recyclerview-v7:${supportLibrary}",

"constraint":"androidx.constraintlayout:constraintlayout:1.1.3",

"design":"com.android.support:design:${supportLibrary}"

? ? ]

}

3.根目錄下的build.gradle頭部加入自定義config.gradle戏仓,相當于layout布局中加入include

????applyfrom:"config.gradle"

4.定義變量引用公共配置文件

? 定義? def androidId =rootProject.ext.androidId

? 引用? compileSdkVersion androidId.compileSdkVersion

????buildToolsVersion androidId.buildToolsVersion

? ? ?dependencies {

????????implementation fileTree(dir:'libs',include: ['*.jar'])

????????support.each { k, v -> implementation v }

????}

一些Gradle用法

def androidId =rootProject.ext.androidId

def appId =rootProject.ext.appId

def support =rootProject.ext.dependencies

def url =rootProject.ext.url

android {

compileSdkVersion androidId.compileSdkVersion

buildToolsVersion androidId.buildToolsVersion

defaultConfig {

applicationId appId.app

minSdkVersion androidId.minSdkVersion

targetSdkVersion androidId.targetSdkVersion

versionCode androidId.versionCode

versionName androidId.versionName

testInstrumentationRunner"androidx.test.runner.AndroidJUnitRunner"

? ? ? ? //開啟分包

? ? ? ? multiDexEnabledtrue

? ? ? ? //設(shè)置分包配置

? ? ? ? multiDexKeepFile file('multidex-config.txt')

//將svg圖片生成指定維度的png圖片

? ? ? vectorDrawables.generatedDensities('xxxhdpi','xxhdpi')

//使用support-v7兼容(5.0版本以上)

? ? ? ? vectorDrawables.useSupportLibrary =true

? ? ? ? //只保留指定和默認資源

? ? ? ? resConfigs('zh-rCN')

ndk {

abiFilters('armeabi-v7a')

}

//源集-設(shè)置源集的屬性疚宇,更改源集的Java目錄或者自由目錄等

? ? ? ? sourceSets {

main {

if (isRelease) {

//如果是組件化模式,需要單獨運行時

? ? ? ? ? ? ? ? ? ? manifest.srcFile'src/main/AndroidManifest.xml'

? ? ? ? ? ? ? ? ? ? java.srcDirs = ['src / main / java']

res.srcDirs = ['src / main / res']

resources.srcDirs = ['src / main / resources']

aidl.srcDirs = ['src / main / aidl']

assets.srcDirs = ['src / main / assets']

}else {

//集成化模式柜去,整個項目打包

? ? ? ? ? ? ? ? ? ? manifest.srcFile'src/main/AndroidManifest.xml'

? ? ? ? ? ? ? ? }

}

}

externalNativeBuild {

cmake {

cppFlags ""

? ? ? ? ? ? }

}

}

//signingConfigs一定要在buildTypes簽名

? ? signingConfigs {

debug {

//天坑:填錯了灰嫉,編譯不通過還找不到問題

? ? ? ? ? ? storeFile file("C:/Users/Administrator/.android/debug.keystore")

????????????storePassword "android"

? ? ? ? ? ? keyAlias "androiddebugkey"

? ? ? ? ? ? keyPassword "android"

? ? ? ? }

release {

//簽名文件

? ? ? ? ? ? storeFile file("D:/Sunjichao/.jks")

//簽名證書的類型

? ? ? ? ? ? storeType ""

? ? ? ? ? ? //簽名證書文件的密碼

? ? ? ? ? ? storePassword ""

? ? ? ? ? ? //簽名證書中的密鑰別名

? ? ? ? ? ? keyAlias ""

? ? ? ? ? ? //簽名證書中該密鑰的密碼

? ? ? ? ? ? keyPassword ""

? ? ? ? ? ? //是否開啟V2打包

? ? ? ? ? ? v2SigningEnabledtrue

? ? ? ? }

}

buildTypes {

debug {

//對構(gòu)建類型設(shè)置簽名信息

? ? ? ? ? ? signingConfig signingConfigs.debug

? ? ? ? ? ? buildConfigField("String","debug","\"${url.debug}\"")

}

release {

signingConfig signingConfigs.release

? ? ? ? ? ? buildConfigField("String","release","\"${url.release}\"")

minifyEnabled false

? ? ? ? ? ? proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),'proguard-rules.pro'

? ? ? ? }

}

//AdbOptions可以對adb操作選項添加配置

? ? adbOptions {

//配置操作超時時間,單位毫秒

? ? ? ? timeOutInMs =5 *1000_0

? ? ? ? //adb install命令的選項配置

? ? ? ? installOptions'-r','-s'

? ? }

//對dx操作的配置嗓奢,接受一個DexOptions類型的閉包讼撒,配置由DexOptions提供

? ? dexOptions {

//配置執(zhí)行dx命令是為其分配最大的對內(nèi)存

? ? ? ? javaMaxHeapSize"4g"

? ? ? ? //配置是否預執(zhí)行dex Libraries工程,開啟后會提高增量構(gòu)建速度股耽,不過會影響clean構(gòu)建的速度根盒,默認為true

? ? ? ? preDexLibraries =false

? ? ? ? //配置是否開啟jumbo模式,代碼方法是超過65535需要強制開啟才能構(gòu)建成功

? ? ? ? jumboModetrue

? ? ? ? //配置Gradle運行dx命令時使用的線程數(shù)量

? ? ? ? threadCount8

? ? ? ? //配置multidex參數(shù)

? ? ? ? additionalParameters = [

'--multi-dex',//多dex分包

? ? ? ? ? ? ? ? '--set-max-idx-number=50000',//每個包內(nèi)方法數(shù)量上限

//'--main-dex-list=' + '/multidex-config.txt',//打包到主classes.dex的文件列表

? ? ? ? ? ? ? ? '--minimal-main-dex'

? ? ? ? ]

}

//執(zhí)行g(shù)radle lint命令即可運行l(wèi)int檢查物蝙,默認生成的報告在outputs/lint-results.html中

? ? lintOptions {

//遇到lint檢查錯誤會終止構(gòu)建炎滞,一般設(shè)置為false

? ? ? ? abortOnErrorfalse

? ? ? ? //將警告當作錯誤來處理,

? ? ? ? warningsAsErrorsfalse

? ? ? ? //檢查新的API

? ? ? ? check'NewApi'

? ? }

externalNativeBuild {

cmake {

path"src/main/cpp/CMakeLists.txt"

? ? ? ? ? ? version"3.10.2"

? ? ? ? }

}

}

dependencies {

implementation fileTree(dir:'libs',include: ['*.jar'])

support.each { k, v -> implementation v }

}

二 組件化項目詳細部署

組件化項目的意義

????1.面試技巧诬乞,在最短時間內(nèi)打動面試官

????2.開發(fā)需求册赛,不相互依賴,可以相互交互震嫉,任意組合森瘪,高度解耦

????3.團隊效率,分模塊打包票堵,測試扼睬,統(tǒng)一版本管理

Phone module和Android Library的區(qū)別

? ? 1.Phone module新建出可以獨立運行的模塊,可以看成是app悴势,配置為"applyplugin:'com.android.application'"

????有applicationId? 切換"com.android.library"

?????2.? Android Library新建出安桌庫窗宇,不能獨立運行。配置為"applyplugin:'com.android.library'"

????無applicationId 切換"com.android.application"

新建comment公共庫特纤、order訂單庫军俊、persional個人信息庫

Gradle搭建組件化項目環(huán)境

集成化開發(fā)模式,組件化開發(fā)模式

組件化開發(fā)的臨時代碼捧存,集成化打包動態(tài)隔離

組件化模式:子模塊可以獨立運行

集成化模式:打包整個項目apk蝇完,子模塊不可獨立運行

當需要發(fā)布正式版本時官硝,就需要集成化將各個子模塊打包成一個apk,而測試時,就分開打包短蜕,將各個模塊分開打包,通過配置gradle來實現(xiàn)切換

//生產(chǎn)/開發(fā)環(huán)境 動態(tài)切換組件化模式或者集成化模式

?1. isRelease =false

?2.? ?if (isRelease) {

????????applyplugin:'com.android.library'

????}else {

????????applyplugin:'com.android.application'

????}

? 3. if (!isRelease) {

????????applicationId appId.module

????}

動態(tài)隔離:將正式發(fā)布版本與測試版本的打包時隔離傻咖,便于開發(fā)過程中打包測試和發(fā)布朋魔。

//源集-設(shè)置源集的屬性,更改源集的Java目錄或者自由目錄等,方便測試環(huán)境卿操,打包不集成到正式環(huán)境

sourceSets {

main {

if (isRelease) {

//集成化模式警检,整個項目打包

? ? ? ? ? ? manifest.srcFile'src/main/AndroidManifest.xml'

? ? ? ? ? ? //release時,debug目錄下文件不需要合并到主工程

? ? ? ? ? ? java{

exclude'**/debug/**'

? ? ? ? ? ? }

}else {

//如果是組件化模式害淤,需要單獨運行時

? ? ? ? ? ? manifest.srcFile'src/main/debug/AndroidManifest.xml'

? ? ? ? }

}

}

三扇雕、子模塊間交互

module與module之間交互(包括跳轉(zhuǎn),傳參等)

方式

1.eventBus? eventBean非常多(一對一)窥摄,一對多就會混亂不堪镶奉、難以維護

2.反射反射技術(shù)可以成功,維護成本較高且容易出現(xiàn)高版本@hide限制崭放。

3.隱式意圖 維護成本還好哨苛,只是比較麻煩,需要維護Manifest中的action

4.BroadcastReceiver 需要動態(tài)注冊(7.0后)币砂,需求方發(fā)送廣播

5.類加載 需要準確的全類名路徑建峭,維護成本較高且容易出現(xiàn)人為失誤

6. ........

還有一種比較實用的方案,全局map,首先在公共庫里面創(chuàng)建一個PathBean class,里面有兩個屬性path和class

再創(chuàng)建一個全局路徑記錄器(RecordPathManager)决摧,在這里面創(chuàng)建全局的map,

private static Map>groupMap =new HashMap<>();

兩個函數(shù)1.將路徑信息加入全局mapjoinGroup(),2.根據(jù)路徑名獲得class對象亿蒸,達到跳轉(zhuǎn)的目的getTargetClass()

/**

* @param groupName 組名,"如order"

* @param pathName? 路徑名 "如com.example.module"

* @param clazz? ? 類對象,如"OrderActivity.class"

*/

public static void joinGroup(String groupName, String pathName, Class clazz) {

List list =groupMap.get(groupName);

? ? if (list ==null) {

list =new ArrayList<>();

? ? ? ? list.add(new PathBean(pathName, clazz));

? ? ? ? groupMap.put(groupName, list);

? ? }else {

for (PathBean pathBean:list){

if(!pathName.equals(pathBean.getPath())){

list.add(new PathBean(pathName,clazz));

? ? ? ? ? ? ? ? groupMap.put(groupName,list);

? ? ? ? ? ? }

}

}

}

/**

* 根據(jù)路徑名獲得class對象掌桩,達到跳轉(zhuǎn)的目的

* @param groupName

* @param pathName

* @return

*/

public static ClassgetTargetClass(String groupName,String pathName){

List list=groupMap.get(groupName);

? ? if(list==null)return null;

? ? for (PathBean pathBean:list){

if(pathName.equalsIgnoreCase(pathBean.getPath())){

return pathBean.getClazz();

? ? ? ? }

}

return null;

}

在application里面添加路徑信息边锁,以便初始化的時候可以加載全部的信息,

@Override

public void onCreate() {

super.onCreate();

? ? RecordPathManager.joinGroup("app","MainActivity", MainActivity.class);

? ? RecordPathManager.joinGroup("module","ModuleActivity", ModuleActivity.class);

? ? RecordPathManager.joinGroup("library","Library_Activity", Library_Activity.class);

}

在需要跳轉(zhuǎn)的地方這樣使用:

Class targeClass= RecordPathManager.getTargetClass("module","ModuleActivity");

if(targeClass==null){

Toast.makeText(Library_Activity.this,"targeClass為null",Toast.LENGTH_LONG).show();

}else {

Intent intent=new Intent(Library_Activity.this,targeClass);

? ? startActivity(intent);

}

這種方法同樣也有詬病的地方拘鞋,比如我的項目中有200個activity忘巧,在application中豈不是要添加200個map數(shù)據(jù)渣窜?

我們可以使用apt,注解處理器來簡化我們的使用過程

四 APT介紹和使用

什么時APT(Annotation Processing Tool)

是一種處理注釋的工具,他對源代碼文件進行檢測找出其中的Annitation,根據(jù)注解自動生成代碼券躁,如果想要自定義的注解處理器能夠正常運行,必須要通過APT工具來進行扛稽,也可以這樣理解柴灯,只有通過聲明APT工具后, 程序在編譯期間自定義的注解? ? 才能執(zhí)行宣旱。

通俗理解:根據(jù)規(guī)則仅父,幫我們生成代碼,生成類文件。?

開發(fā)環(huán)境兼容

Android studio 3.3.2+Gradle4.10.1(臨界版本)

Android studio 3.4.1+Gradle5.1.1(向下兼容)

Target該注解作用域的目標

Activity使用的布局文件注解???

@Target(ElementType.TYPE)? ? //接口笙纤,類耗溜,枚舉,注解

@Target(ElementType.FIELD)? ? //屬性省容、枚舉的常量

@Target(ElementType.METHOD)//方法

@Target(ElementType.PARAMETER)//方法參數(shù)

@Target(ElementType.CONSTRUCTOR)//構(gòu)造方法

@Target(ElementType.LOCAL_VARIABLE)//局部變量

@Target(ElementType.ANNOTATION_TYPE)//該注解使用在另一個注解中

@Target(ElementType.PACKAGE)? ? ? ? //包

@RETENTION(RetentionPolicy.RUNTIME)//注解會在class字節(jié)碼中存在抖拴,jvm加載時,可以通過反射獲得該注解中的內(nèi)容腥椒。

生命周期 SOURCE<CLASS<RUNTIME

一般如果需要在運行時去動態(tài)獲得注解的內(nèi)容阿宅,用RUNTIME注解

要在編譯時進行一些預處理工作,如ButterKnife,用CLASS注解笼蛛,注解會在class文件中存在洒放,但是在運行時會被丟棄。

做一些檢查性操作滨砍,如@override,用SOURCE注解源碼往湿,注解僅存在源碼級別,在編譯的時候丟棄該注解

1.首先創(chuàng)建一個Java工程存放注解 標注該注解作用域和生命周期惨好。

????@Target(ElementType.TYPE)

????@Retention(RetentionPolicy.CLASS)

????public @interface ARouter {

????????//詳細的路由路徑煌茴,必填 如"app/MainActivity"

????? ? Stringpath();

????? ? //從path中取出,規(guī)范開發(fā)者的編碼日川。

? ????? Stringgroup()default "";

????}

? ? 2.創(chuàng)建注解管理器蔓腐,主要作用是生成注解文件,返回當前使用注解的類

? ? ? ?(1) 在compiler中build.gradle中配置

????????//不可缺少龄句,注冊注解回论,并且生成文件

? ????? compileOnly'com.google.auto.service:auto-service:1.0-rc4'

? ????? annotationProcessor'com.google.auto.service:auto-service:1.0-rc4'

? ????? implementation project(':annotation')

????????//java控制臺亂碼

????? ? tasks.withType(JavaCompile){

????????options.encoding="utf-8"

????? ? }

????}

????//jdk編譯的版本是1.7

????sourceCompatibility ="7"

????targetCompatibility ="7"

? ? (2)通過重寫AbstractProcessor,獲得當前使用該注解的作用的名稱等信息分歇,并且動態(tài)

????????生成Library_Activity$$ARouter傀蓉,返回想要的屬性加載到內(nèi)存中,


@AutoService(Processor.class)//通過AutoService自動生成注解處理器

@SupportedAnnotationTypes({"com.example.annotation.ARouter"})

@SupportedSourceVersion(SourceVersion.RELEASE_7)

@SupportedOptions("content")

public class ARouterProcessorextends AbstractProcessor {

//操作Element工具類

? ? private ElementselementUtils;

? ? //type(類信息)工具類

? ? private TypestypeUtils;

? ? //用來輸出錯誤 警告等信息

? ? private Messagermessager;

? ? //文件生成器

? ? private Filerfiler;

? ? @Override

? ? public synchronized void init(ProcessingEnvironment processingEnvironment) {

super.init(processingEnvironment);

? ? ? ? elementUtils = processingEnvironment.getElementUtils();

? ? ? ? typeUtils = processingEnvironment.getTypeUtils();

? ? ? ? messager = processingEnvironment.getMessager();

? ? ? ? filer = processingEnvironment.getFiler();

? ? ? ? String content = processingEnvironment.getOptions().get("content");

? ? ? ? messager.printMessage(Diagnostic.Kind.NOTE, content);

? ? }

//可以用注解方式

//? ? @Override

//? ? public Set getSupportedAnnotationTypes() {

//? ? ? ? return super.getSupportedAnnotationTypes();

//? ? }

//? ? //必填

//? ? @Override

//? ? public SourceVersion getSupportedSourceVersion() {

//? ? ? ? return super.getSupportedSourceVersion();

//? ? }

//

//? ? @Override

//? ? public Set getSupportedOptions() {

//? ? ? ? return super.getSupportedOptions();

//? ? }

? ? /**

* 相當于main函數(shù)职抡,開始處理注解

* 注解處理器的核心方法葬燎,處理具體的注解,生成Java文件

*

? ? * @param set? ? ? ? ? ? ? 使用了支持處理的節(jié)點集合(類 上面寫了集合)

? ? * @param roundEnvironment 當前或是之前的運行環(huán)境缚甩,可以通過該對象查找找到該注解

? ? * @return true表示后續(xù)處理器不會再處理(已經(jīng)處理完成)

*/

? ? @Override

? ? public boolean process(Set set, RoundEnvironment roundEnvironment) {

if (set.isEmpty())return false;

? ? ? ? //獲取所有使用了Arouter注解的集合

? ? ? ? Set elements = roundEnvironment.getElementsAnnotatedWith(ARouter.class);

? ? ? ? for (Element element : elements) {

//類節(jié)點之上就是包節(jié)點

? ? ? ? ? ? String packageName =elementUtils.getPackageOf(element).getQualifiedName().toString();

? ? ? ? ? ? //獲取簡單類名

? ? ? ? ? ? String className = element.getSimpleName().toString();

? ? ? ? ? ? messager.printMessage(Diagnostic.Kind.NOTE, "被注解的類有:" + className);

? ? ? ? ? ? //最終我們想要生成的類文件

? ? ? ? ? ? String finalClassName = className +"$$ARouter";

? ? ? ? ? ? try {

JavaFileObject sourceFile =filer.createSourceFile(packageName +"." + finalClassName);

? ? ? ? ? ? ? ? Writer writer = sourceFile.openWriter();

? ? ? ? ? ? ? ? //設(shè)置包名

? ? ? ? ? ? ? ? writer.write("package " + packageName +";\n");

? ? ? ? ? ? ? ? writer.write("public class " + finalClassName +"{\n");

? ? ? ? ? ? ? ? writer.write("public static Class<?> findTargetClass(String path){\n");

? ? ? ? ? ? ? ? //獲取類之上ARouter注解的path值

? ? ? ? ? ? ? ? ARouter aRouter = element.getAnnotation(ARouter.class);

? ? ? ? ? ? ? ? writer.write("if(path.equalsIgnoreCase(\""+aRouter.path()+"\")){\n");

? ? ? ? ? ? ? ? writer.write("return "+className+".class;\n}\n");

? ? ? ? ? ? ? ? writer.write("return null;\n");

? ? ? ? ? ? ? ? writer.write("}\n}");

? ? ? ? ? ? ? ? //非常重要

? ? ? ? ? ? ? ? writer.close();

? ? ? ? ? ? }catch (IOException e) {

e.printStackTrace();

? ? ? ? ? ? }

}

return true;

? ? }

}

(3)在使用的包內(nèi)掃描注解處理器谱净,利用@SupportedOptions({"content"})將Java工程和application工程建立橋梁

//掃描注解處理器

annotationProcessor project(':compiler')

//在gradle中,配置選項參數(shù)值(只用于apt傳參)

//切記:必須寫在defaultConfig節(jié)點下

javaCompileOptions{

annotationProcessorOptions{

arguments=[content:'hello apt']

}

}

(4)在activity內(nèi)使用

//得到注解的信息

Class targeClass= Library_Activity$$ARouter.findTargetClass("/library/Library_Activity");

五 APT高級用法JavaPoet

什么事JavaPoet?

APT+JavaPoet=超級利刃

JavaPoet是square公司推出的開源Java代碼生成框架擅威,提供Java api生成.Java源文件壕探,這個框架功能非常實用,也是我們習慣的Java面向?qū)ο驩OP語法郊丛,可以很方便的使用它根據(jù)注解生成代碼李请,通過這種自動化生成代碼的方式瞧筛,可以讓我們更加簡潔優(yōu)雅的方式替換繁瑣冗雜的重復工作。

依賴JavaPoet

implementation' com.squareup:javapoet:1.9.0'

JavaPoet常用庫

? ? MethodSpec? ? ? ? ? ? 代表一個構(gòu)造函數(shù)或方法聲明

? ? TypeSpec? ? ? ? ? ? ? ? 代表一個類导盅、接口较幌、枚舉的聲明

? ? FieldSpec? ? ? ? ? ? ? ? 代表一個成員變量,一個字段的聲明

? ? JavaFile? ? ? ? ? ? ? ? ? ? 包含一個頂級類的Java文件

? ? ParameterSpec? ? ? ? 用來創(chuàng)建參數(shù)

? ? AnnotationSpec? ? ? ? 用來創(chuàng)建注解

? ? ClassName? ? ? ? ? ? ? ? 用來包裝一個類

? ? TypeName? ? ? ? ? ? ? ? ? 類型(如在添加返回值類型是使用TypeName.VOID)? ?

JavaPoet字符串格式化規(guī)則

$L????字面量????如"int value=$L",10

$S? ? 字符串????如 $S ,"hello"

$T? ? 接口?????????如?$T,MainActiivity

$N? ? 變量??????????如 user:$N,name

使用步驟同上面一摸一樣认轨,只是在AnnotationProcessor生成file的時候有所改變绅络,沒有那么多writer.write

//使用JavaPoet

ARouter aRouter=element.getAnnotation(ARouter.class);

MethodSpec methodSpec= MethodSpec.methodBuilder("findTargetClass")

.addModifiers(Modifier.PUBLIC,Modifier.STATIC)

.returns(Class.class)

.addParameter(String.class,"path")

.addStatement("return path.equals($S) ?$T.class : null",aRouter.path(), ClassName.get((TypeElement)element))

.build();

TypeSpec typeSpec=TypeSpec.classBuilder(finalClassName)

.addModifiers(Modifier.PUBLIC,Modifier.FINAL)

.addMethod(methodSpec)

.build();

JavaFile javaFile= JavaFile.builder(packageName,typeSpec).build();

try {

javaFile.writeTo(filer);

}catch (IOException e) {

e.printStackTrace();

}

六 路由架構(gòu)的設(shè)計

在組件化的架構(gòu)中,我們需要通過APT和JavaPoet技術(shù)生成什么樣的類文件呢嘁字?

為什么需要組名?

????避免程序一打開杉畜,所有信息全部加載進內(nèi)存纪蜒,節(jié)省內(nèi)存,提高性能

生成這些文件做什么用

? ? 通過組信息此叠,找到路徑文件記錄纯续,再在路徑文件記錄里面匹配,返回class信息灭袁。達到跳轉(zhuǎn)的目的猬错。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市茸歧,隨后出現(xiàn)的幾起案子倦炒,更是在濱河造成了極大的恐慌,老刑警劉巖软瞎,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逢唤,死亡現(xiàn)場離奇詭異,居然都是意外死亡涤浇,警方通過查閱死者的電腦和手機鳖藕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來只锭,“玉大人著恩,你說我怎么就攤上這事◎哒梗” “怎么了喉誊?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長铺呵。 經(jīng)常有香客問我裹驰,道長,這世上最難降的妖魔是什么片挂? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任幻林,我火速辦了婚禮贞盯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沪饺。我一直安慰自己躏敢,他們只是感情好,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布整葡。 她就那樣靜靜地躺著件余,像睡著了一般。 火紅的嫁衣襯著肌膚如雪遭居。 梳的紋絲不亂的頭發(fā)上啼器,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音俱萍,去河邊找鬼端壳。 笑死,一個胖子當著我的面吹牛枪蘑,可吹牛的內(nèi)容都是我干的损谦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼岳颇,長吁一口氣:“原來是場噩夢啊……” “哼照捡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起话侧,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤栗精,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后掂摔,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體术羔,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年乙漓,在試婚紗的時候發(fā)現(xiàn)自己被綠了级历。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡叭披,死狀恐怖寥殖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情涩蜘,我是刑警寧澤嚼贡,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站同诫,受9級特大地震影響粤策,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜误窖,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一叮盘、第九天 我趴在偏房一處隱蔽的房頂上張望秩贰。 院中可真熱鬧,春花似錦柔吼、人聲如沸毒费。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽觅玻。三九已至,卻和暖如春培漏,著一層夾襖步出監(jiān)牢的瞬間溪厘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工牌柄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留桩匪,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓友鼻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親闺骚。 傳聞我的和親對象是個殘疾皇子彩扔,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容