Android路由框架-ARouter使用以及遇到的問題


一、頁面路由基本介紹

1.什么是頁面路由

  映射頁面跳轉關系,包含跳轉相關的URL跳轉及值傳遞、攔截器等功能。

2.為什么要使用頁面路由

  在原始android開發中,當我們需要進行頁面跳轉時,正常寫法如下:

Intent intent = new Intent(mContext, XXActivity.class); intent.putExtra("key","value"); startActivity(intent); Intent intent = new Intent(mContext, XXActivity.class); intent.putExtra("key","value"); startActivityForResult(intent, 100); 

上述寫法容易出現以下問題:

  1. 多人協同開發的時候,大家都去AndroidManifest.xml中定義各種IntentFilter,使用隱式Intent,最終發現AndroidManifest.xml中充斥着各種Schame,各種Path,需要經常解決Path重疊覆蓋、過多的Activity被導出,引發安全風險等問題
  2. 跳轉過程中無法插手:直接通過Intent的方式跳轉,跳轉過程開發者無法干預,一些面向切面的事情難以實施,比方說登錄、埋點這種非常通用的邏輯,在每個子頁面中判斷又很不合理,畢竟activity已經實例化了
  3. 跨模塊無法顯式依賴:在App小有規模的時候,我們會對App做水平拆分,按照業務拆分成多個子模塊,之間完全解耦,通過打包流程控制App功能,這樣方便應對大團隊多人協作,互相邏輯不干擾,這時候只能依賴隱式Intent跳轉,書寫麻煩,成功與否難以控制

    二、頁面路由框架ARouter介紹

    1.常用功能介紹

    應用內頁面跳轉

    添加依賴

    溫馨提示:api 的版本和 compiler 的版本號需要用最新的。最新的版本在 Github上可以找到。

    重寫Application並初始化ARouter   配置將要跳轉的頁面

  4. 進行簡單的頁面跳轉

  5. 溫馨提示:支持數據類型如下:
    
    //基礎類型
    .withString( String key, String value )
    .withBoolean( String key, boolean value)
    .withChar( String key, char value )
    .withShort( String key, short value)
    .withInt( String key, int value)
    .withLong( String key, long value)
    .withDouble( String key, double value)
    .withByte( String key, byte value)
    .withFloat( String key, float value)
    .withCharSequence( String key,  CharSequence value)
    
    //數組類型
    .withParcelableArrayList( String key, ArrayList<? extends Parcelable > value)
    .withStringArrayList( String key,  ArrayList<String> value)
    .withIntegerArrayList( String key, ArrayList<Integer> value)
    .withSparseParcelableArray( String key, SparseArray<? extends Parcelable> value)
    .withCharSequenceArrayList( String key, ArrayList<CharSequence> value)
    .withShortArray( String key,  short[] value)
    .withCharArray( String key, char[] value)
    .withFloatArray( String key, float[] value)
    .withCharSequenceArray( String key,  CharSequence[] value)
    
    //Bundle 類型
    .with( Bundle bundle )
    
    //Activity 跳轉動畫
    .withTransition(int enterAnim, int exitAnim)
    
    //其他類型
    .withParcelable( String key, Parcelable value)
    .withParcelableArray( String key,  Parcelable[] value)
    .withSerializable( String key, Serializable value)
    .withByteArray( String key, byte[] value)
    .withTransition(int enterAnim, int exitAnim)
    

    三:遇到的問題

    • ARouter.getInstance().inject(this);
      我們有一個singletask啟動模式的activity,在onNewIntent方法中調用ARouter.getInstance().inject(this);得不到參數,查看ARouter在build過程中生成的代碼可以知道它是調用了activity的getIntent來獲取參數的,但是onNewIntent中的intent和在onCreate方法中的intent並不相同,所以需要在onNewIntent方法中調用setIntent方法,然后就能得到參數了。

      ARouter::Compiler >>> No module name, for more information, look at gradle log.
      檢查項目依賴的全部module包括module依賴的module(沒有頁面的module也算),在每個module的 build.gradle中加上下面的代碼。

    defaultConfig {
        
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [ AROUTER_MODULE_NAME : project.getName() ]
                }
            }
    }
    • ARouter there's no route matched

    不同module的一級路徑必須不同,否則會導致一個moudle中的一級路徑失效

    下面是拋出異常的源代碼

        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 {
            //查找到路由地址
            。。。。。
        }
    }

     

    by:yzl


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM