Arouter 框架是主要由三個模塊組成,annotation,compiler,core.java
annotation :自定義註解,用來聲明須要路由的頁面(Java Library)android
compiler :註解解析,在編譯時根據自定義註解生成註冊路由表的java類(Java Library)。bash
core : 實現路由跳轉功能,供Android調用(Android Library)框架
先上工程結構圖ide
新建一個文件,編寫一個註解,聲明路由路徑函數
RouteMeta保存路由信息,經過解析註解獲取。工具
獲取Activity類的節點信息,而後循環,判斷是Activity類型的節點,新建RouteMeta對象保存節點信息。而後調用categories()驗證節點的路由地址是否符合規則,再根據分組名保存節點到groupMap中post
遍歷groupMap中的節點信息,使用javapoet工具生成一個繼承IRouteGroup接口的java類,用來保存每一個分組的路由信息。叫分組信息類。ui
而後遍歷全部的分組信息類,生成繼承IRouteRoot接口的表信息類,保存分組名對應的分組信息類。this
Postcard繼承RouteMeta類,保存路由地址、分組名以及要傳遞的數據。使用Postcard的with方法添加傳遞的數據,調用Postcard的navigation()進行頁面跳轉
public class Postcard extends RouteMeta {
private Bundle mBundle;
//新版風格
private Bundle optionsCompat;
private int flags = -1;
public Postcard(String path, String group) {
this(path, group, null);
}
public Postcard(String path, String group, Bundle bundle) {
setPath(path);
setGroup(group);
this.mBundle = (null == bundle ? new Bundle() : bundle);
}
public Bundle getExtras() {return mBundle;}
public Bundle getOptionsBundle() {
return optionsCompat;
}
/**
* Intent.FLAG_ACTIVITY**
* @param flag
* @return
*/
public Postcard withFlags(int flag) {
this.flags = flag;
return this;
}
public Postcard withString(String key,String value){
mBundle.putString(key,value);
return this;
}
public Postcard withInt(String key,int value){
mBundle.putInt(key,value);
return this;
}
public Postcard withBoolean(String key,boolean value){
mBundle.putBoolean(key,value);
return this;
}
public int getFlags() {
return flags;
}
public Object navigation() {
return ToolRouter.getInstance().navigation(null, this, -1, null);
}
public Object navigation(Context context) {
return ToolRouter.getInstance().navigation(context, this, -1, null);
}
public Object navigation(Context context, NavigationCallback callback) {
return ToolRouter.getInstance().navigation(context, this, -1, callback);
}
public Object navigation(Context context, int requestCode) {
return ToolRouter.getInstance().navigation(context, this, requestCode, null);
}
public Object navigation(Context context, int requestCode, NavigationCallback callback) {
return ToolRouter.getInstance().navigation(context, this, requestCode, callback);
}
}
複製代碼
調用Postcard的navigation()進行跳轉。
protected Object navigation(Context context, final Postcard postcard, final int requestCode,
final NavigationCallback callback) {
try {
//準備卡片,路由信息
prepareCard(postcard);
} catch (NoRouteFoundException e) {
e.printStackTrace();
if (null != callback) {
callback.onLost(postcard);
}
return null;
}
if (null != callback) {
callback.onFound(postcard);
}
switch (postcard.getType()) {
case ACTIVITY:
final Context currentContext = null == context ? mContext : context;
final Intent intent = new Intent(currentContext, postcard.getDestination());
intent.putExtras(postcard.getExtras());
int flags = postcard.getFlags();
if (-1 != flags) {
intent.setFlags(flags);
} else if (!(currentContext instanceof Activity)) {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
mHandler.post(new Runnable() {
@Override
public void run() {
//帶返回碼
if(requestCode > 0 ){
ActivityCompat.startActivityForResult((Activity) currentContext,intent,requestCode,postcard.getExtras());
}else {
ActivityCompat.startActivity(currentContext,intent,postcard.getExtras());
}
if(null != callback){
callback.onArrival(postcard);
}
}
});
break;
}
return null;
}
複製代碼
先準備路由的卡片信息,若是沒有準備路由信息,根據分組名從Warehouse的groupsIndex中找到分組信息類,加載對應路由表的信息。這裏實現了按需加載。獲取到路由信息後,設置postcard的信息。再調用startActivity來跳轉
private void prepareCard(Postcard postcard) {
RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());
if (null == routeMeta) {//尚未準備信息
//建立並調用 loadinto 函數 而後記錄在倉庫
Class<? extends IRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard
.getGroup());
if (null == groupMeta) {
throw new NoRouteFoundException("沒找到對應路由: " + postcard.getGroup() + " " +
postcard.getPath());
}
IRouteGroup iGroupInstance = null;
try {
iGroupInstance = groupMeta.getConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
}
iGroupInstance.loadInto(Warehouse.routes);
//已經準備過了就能夠移除了
Warehouse.groupsIndex.remove(postcard.getGroup());
//再次進入else
prepareCard(postcard);
} else {
//獲取要跳轉的activity
postcard.setDestination(routeMeta.getDestination());
postcard.setType(routeMeta.getType());
// switch (routeMeta.getType()){
//
// }
}
}
複製代碼
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
initToolRouter();
}
private void initToolRouter() {
ToolRouter.init(this);
}
}
複製代碼
2.在FirstActivity 和MainActivity中添加註解,在MainActivity中點擊按鈕進行跳轉
@Route(path = "/demo1/fisrtActivity")
public class FirstActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
}
}
複製代碼
@Route(path = "/demo2/MainActivity")
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button jump_btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
jump_btn = findViewById(R.id.jump_btn);
jump_btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.jump_btn:
ToolRouter.getInstance().build("/demo1/fisrtActivity")
.navigation();
break;
}
}
}
複製代碼