1. 程式人生 > >ARouter there's no route matched解決方法

ARouter there's no route matched解決方法

原因

ARouter是一個元件化開發常用的一個路由框架,它可以很方便的讓我們進行元件之間的跳轉。但是隨著module的增多我們很容易出現there’s no route matched的錯誤,出現這種問題會讓我們在開發的時候很麻煩,卻又沒有報錯的日誌讓我們檢視。
在百度了很多之後發現網上的方法都不能解決我的問題,於是通過簡單的原始碼閱讀,找到了問題所在。

#分析

Aouter的具體使用便不再說了,下面首先從Aouter的使用方法入手:

    ARouter.getInstance().build(path).navigation();

直接ctrl點進程式碼,顯示呼叫順序:

再繼續點進去:


發現最終呼叫的方法是:

    LogisticsCenter.completion(postcard);

檢視這個方法的原始碼:

在這裡終於找到了“There is no route match the path”這個提示的產生地方。

程式碼分析

這是一個尋找router path的一段程式碼,簡單的來說,就是找到了就進行路由跳轉,找不到就提示錯誤。

    public synchronized static void completion(Postcard postcard) {
    if (null == postcard) {
        throw new NoRouteFoundException(TAG + "No postcard!");
    }

    //查詢RouteMeta物件,如果存在說明路由成功,如果失敗說明還沒有被載入或者這個path就是錯誤的
    RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());
    if (null == routeMeta) {
      // 通過groupsIndex去找IRouteGroup的實現類
        Class<? extends IRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard.getGroup());
        if (null == groupMeta) {
            throw new NoRouteFoundException(TAG + "There is no route match the path [" + postcard.getPath() + "], in group [" + postcard.getGroup() + "]");
        } else {
            // 通過反射獲取IRouteGroup的實現類,然後載入到記憶體
            IRouteGroup iGroupInstance = groupMeta.getConstructor().newInstance();
            iGroupInstance.loadInto(Warehouse.routes);
            // 載入到記憶體後Warehouse.groupsIndex去掉這個group
            Warehouse.groupsIndex.remove(postcard.getGroup());
        }
    } else {
        //查詢到路由地址
        。。。。。
    }
}

IRouterGroup的實現類如下:

這裡的path都是”/app/xxxx/”,Aouter 要求path必須有至少兩級的路徑,是因為Arouter在尋找route的時候,是通過第一級路徑,也就是這裡的”app”來尋找的。Aouter通過”app”找到了route,並且在groupIndex中刪除了這個路徑,代表已經載入到了記憶體。ARouter

G r o u
p
app就是這個尋找地址的自動生成類。
這時候我們在編譯器中尋找一下這個的程式碼,意外發現有兩個ARouter G r o u p app存在。

現在的問題已經很明顯了,不同的module使用了相同的一級路徑,在Arouter第一次尋找到route的時候便刪除了這個一級路徑的group,因為一級路徑的重複,再呼叫另一個module的一級路徑是”app”的路由時,由於之前Warehouse.groupsIndex已經刪除,便導致了there’s no route matched的錯誤。

總結

分析和原因解釋比較簡單,至於怎麼解決,就一句話:
不同module的一級路徑必須不同,否則會導致一個moudle中的一級路徑失效!!!