前面已經(jīng)解析過ARouter的基本用法,還不清楚使用方式的讀者請閱讀
ARouter的基本用法
ARouter 原理
ARouter就是基于反射和注解來解決這個問題的
ARouter在編譯期的時候,利用自定義注解完成了頁面的自動注冊。代碼編譯一遍,可以看到ARouter生成下面幾個源文件:
加上注解@Route(“/group/name”),注意這里需要至少兩層路徑(第一個是分組,第二個一般是類名)。
全部都以group的名字為key,以注解生成的不同的group的類的class對象為value放入到一個map中。
用過ARouter路由框架的同學(xué)應(yīng)該都知道,在每個需要對其他module提供調(diào)用的Activity中,都會聲明類似下面@Route注解,我們稱之為路由地址
@Route(path = "/main/main")
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
@Route(path = "/module1/module1main")
public class Module1MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_module1_main);
}
}
路由框架會在項目的編譯期通過注解處理器掃描所有添加@Route注解的Activity類,然后將Route注解中的path地址和Activity.class文件映射關(guān)系保存到它自己生成的java文件中。為了讓大家理解,我這里來使用近乎偽代碼給大家簡單演示一下。
public class MyRouters{
//項目編譯后通過apt生成如下方法
public static HashMap<String, ClassBean> getRouteInfo(HashMap<String, ClassBean> routes) {
route.put("/main/main", MainActivity.class);
route.put("/module1/module1main", Module1MainActivity.class);
route.put("/login/login", LoginActivity.class);
}
}
這樣我們想在app模塊的MainActivity跳轉(zhuǎn)到login模塊的LoginActivity,那么便只需調(diào)用如下:
//不同模塊之間啟動Activity
public void login(String name, String password) {
HashMap<String, ClassBean> route = MyRouters.getRouteInfo(new HashMap<String, ClassBean>);
LoginActivity.class classBean = route.get("/login/login");
Intent intent = new Intent(this, classBean);
intent.putExtra("name", name);
intent.putExtra("password", password);
startActivity(intent);
}
實際上它的核心思想跟上面講解是一樣的,我們在代碼里加入的@Route注解,會在編譯時期通過apt生成一些存儲path和activity.class映射關(guān)系的類文件,然后app進程啟動的時候會加載這些類文件,把保存這些映射關(guān)系的數(shù)據(jù)讀到內(nèi)存里(保存在map里),然后在進行路由跳轉(zhuǎn)的時候,通過build()方法傳入要到達頁面的路由地址,ARouter會通過它自己存儲的路由表找到路由地址對應(yīng)的Activity.class(activity.class = map.get(path)),然后new Intent(context, activity.Class),當(dāng)調(diào)用ARouter的withString()方法它的內(nèi)部會調(diào)用intent.putExtra(String name, String value),調(diào)用navigation()方法,它的內(nèi)部會調(diào)用startActivity(intent)進行跳轉(zhuǎn),這樣便可以實現(xiàn)兩個相互沒有依賴的module順利的啟動對方的Activity了。
Activity類上加上@Route注解之后,便可通過apt生成對應(yīng)的路由表。
APT是Annotation Processing Tool的簡稱,即注解處理工具。apt是在編譯期對代碼中指定的注解進行解析,然后做一些其他處理(如通過javapoet生成新的Java文件)。
我們常用的ButterKnife,其原理就是通過注解處理器在編譯期掃描代碼中加入的@BindView、@OnClick等注解進行掃描處理,然后生成XXX_ViewBinding類,實現(xiàn)了view的綁定。