Android路由框架-ARouter詳解

来源:https://www.cnblogs.com/WUXIAOCHANG/archive/2019/03/18/10550408.html
-Advertisement-
Play Games

文章大綱 一、頁面路由基本介紹1.什麼是頁面路由2.為什麼要使用頁面路由二、頁面路由框架ARouter介紹1.常用功能介紹2.常見應用場景三、源碼下載四、參考文章 一、頁面路由基本介紹 1.什麼是頁面路由 映射頁面跳轉關係,包含跳轉相關的URL跳轉及值傳遞、攔截器等功能。 2.為什麼要使用頁面路由 ...


文章大綱

一、頁面路由基本介紹
1.什麼是頁面路由
2.為什麼要使用頁面路由
二、頁面路由框架ARouter介紹
1.常用功能介紹
2.常見應用場景
三、源碼下載
四、參考文章

 

一、頁面路由基本介紹

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

   

配置將要跳轉的頁面

 

進行簡單的頁面跳轉

 

 

溫馨提示:如果你想實現像 startActivityForResult() 功能,可以這樣使用

 

運行結果如下:

   

攜帶參數進行頁面跳轉

 

溫馨提示:支持數據類型如下:

//基礎類型
.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)
 

運行程式,結果如下圖所示:

   

路由監聽
在路由跳轉的過程中,我們可以監聽路由的過程,只需要以下使用:

navigation(Context context, NavigationCallback callback)

NavigationCallback 的源碼如下:

public interface NavigationCallback {

    /**
     * Callback when find the destination.
     * 找到了
     * @param postcard meta
     */
    void onFound(Postcard postcard);

    /**
     * Callback after lose your way.
     * 找不到了
     * @param postcard meta
     */
    void onLost(Postcard postcard);

    /**
     * Callback after navigation.
     * 跳轉完了
     * @param postcard meta
     */
    void onArrival(Postcard postcard);

    /**
     * Callback on interrupt.
     * 被攔截了
     * @param postcard meta
     */
    void onInterrupt(Postcard postcard);
}

添加用於測試跳轉的頁面

   

在跳轉的頁面中添加監聽代碼

 

運行結果如下:

     

攔截器使用
添加需要跳轉的頁面

 

添加攔截器

 

在主頁面進行跳轉攔截測試

 

路由分組
在前面我們講到在對 Activity1 做註解的時候,用到了

@Route(path = "/com/Activity1")
public class Activity1 extends AppCompatActivity {}

  在 path 這個字元串裡面,”com” 就代表組的標識;“Activity1” 代表是 Activity1 類的具體表示。組的標識和類的標識都可以自己定義的,需要記住的是組標識和類標識之間用斜杠來區分 ”\” .

什麼是組?
  這裡就需要提下,ARouter框架是分組管理,按需載入。提起來很高深的樣子呢!其實解釋起來就是,在編譯期框架掃描了所有的註冊頁面/服務/欄位/攔截器等,那麼很明顯運行期不可能一股腦全部載入進來,這樣就太不和諧了。所以就分組來管理,ARouter在初始化的時候只會一次性地載入所有的root結點,而不會載入任何一個Group結點,這樣就會極大地降低初始化時載入結點的數量。比如某些Activity分成一組,組名就叫test,然後在第一次需要載入組內的某個頁面時再將test這個組載入進來。

測試一下:

ARouter.getInstance()
       .build("/wxc/Activity1")
       .navigation(this, new NavCallback() {
            @Override
            public void onArrival(Postcard postcard) {
                String group = postcard.getGroup();
                Log.e("zhao", "分組是: " + group);
            }
        });

結果是

07-27 17:32:17.880 19449-19449/com.router E/zhao: 分組是: wxc

ARouter 預設情況下的分組就是第一個 / / 之間的內容。

自定義分組
  創建 CustomGroupActivity 並且添加 註解,並且指定路由分組。自定義分組的就是在原來的註解上添加 group 欄位, 如下所示。

@Route(path = "/com/CustomGroupActivity" , group = "customGroup")
public class CustomGroupActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_group);
    }
}

自定義分組,發起路由:第二個參數就是路由的分組

build(String path, String group)

具體實現如下所示:

 ARouter.getInstance().build("/com/CustomGroupActivity", "customGroup").navigation();

URL 跳轉
web url 跳轉流程圖

 

創建URL 中間跳轉頁
創建 URLReceiveActivity

/**
 * URL 中轉Activity
 */
public class URLReceiveActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView( R.layout.activity_url_receive );

        //對URI 數據分發
        Uri uri = getIntent().getData();
        ARouter.getInstance().build(uri).navigation(this, new NavCallback() {
            @Override
            public void onArrival(Postcard postcard) {
                finish();
            }
        });
    }
}

URLReceiveActivity 添加註冊

<activity android:name=".URLReceiveActivity">
      <!-- Schame -->
      <intent-filter>
            <data
                android:host="zhaoyanjun"
                android:scheme="arouter" />

          <action android:name="android.intent.action.VIEW" />
          <category android:name="android.intent.category.DEFAULT" />
          <category android:name="android.intent.category.BROWSABLE" />

       </intent-filter>

</activity>

這裡面的 host 、scheme 欄位很重要。點擊 url 會根據這兩個欄位會調起本地的 Activity 。

下麵是一段 HTML 片段

<h2>1:URL普通跳轉</h2>

<p><a href="arouter://zhaoyanjun/com/URLActivity1">arouter://zhaoyanjun/com/URLActivity1 </a>
</p>

<h2>2:URL普通跳轉攜帶參數</h2>

<p>
<a href="arouter://zhaoyanjun/com/URLActivity2?name=alex&age=18&boy=true&high=180&obj=%7b%22name%22%3a%22jack%22%2c%22id%22%3a666%7d">arouter://zhaoyanjun/test/URLActivity2?name=alex&age=18&boy=true&high=180&obj={"name":"jack","id":"666"}
</a>
</p>

註意 a 標簽裡面的 arouter://zhaoyanjun 分別代表著 scheme 、host ;/com/URLActivity1 就是目標 Activity 的註解。

如果需要接收 URL 中的參數,需要在 Activity 調用自動註入初始化方法;

ARouter.getInstance().inject(this);

需要註意的是,如果不使用自動註入,那麼可以不寫 ARouter.getInstance().inject(this),但是需要取值的欄位仍然需要標上 @Autowired 註解,因為 只有標上註解之後,ARouter才能知道以哪一種數據類型提取URL中的參數並放入Intent中,這樣您才能在intent中獲取到對應的參數

具體的代碼如下:

@Route(path = "/com/URLActivity2")
public class URLActivity2 extends AppCompatActivity{

    private TextView textView;

    @Autowired
    String name;

    @Autowired
    int age;

    @Autowired
    boolean boy;

    @Autowired
    int high;

    @Autowired
    String obj ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ARouter.getInstance().inject(this);
        setContentView(R.layout.activity_url2);

        textView = (TextView) findViewById(R.id.tv);

        //解析參數
        Bundle bundle = getIntent().getExtras();
        String name1 = bundle.getString("name");

        textView.setText("參數是: " + "name: " + name + "  age: " + age
                + " boy: " + boy + " name1: " + name1 + " obj: " + obj.toString() );
    }
}

效果圖如下:

 

暴露服務
  這裡說到的服務不是Android四大組件中的Service,這裡的服務是介面開發的概念,就是將一部分功能和組件封裝起來成為介面,以介面的形式對外提供能力,所以在這部分就可以將每個功能作為一個服務,而服務的實現就是具體的業務功能。

我們先自定義一個介面 IService 並且繼承 IProvider 。IService 介面裡面有一個 sayHello() 方法,具體代碼如下。

public interface IService extends IProvider {
    void sayHello(Context context );
}

先定義一個 IService 的實現類 MyService 並且添加註解,代碼如下

@Route(path = "/service/hello", name = "測試服務")
public class MyService implements IService {

    @Override
    public void sayHello( Context context ) {
        Toast.makeText(  context , "hello", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void init(Context context) {

    }
}

發現服務,首先定義服務對象,並且添加註解,我們不需要知道介面的具體實現類。

@Autowired(name = "/service/hello")
IService service;

然後添加註解初始化,自動賦值。

ARouter.getInstance().inject(this);

最後我們調用 service 裡面的 sayHello() 方法。

service.sayHello(this);

發現服務這個功能的特點在於,我們只需要知道介面,不需要關心介面的實現類,很好了實現瞭解耦。

路由關閉

ARouter.getInstance().destroy();

溫馨提示:該功能慎用,搞不好整個app頁面跳轉就gg了。

代碼混淆
  如果我們使用了Proguard進行代碼混淆,可以添加以下代碼

-keep public class com.alibaba.android.arouter.routes.**{*;}
-keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;}

2.常見應用場景

  1. 從外部URL映射到內部頁面,以及參數傳遞與解析
    說明:該場景使用到了該文章的URL跳轉和暴露服務功能,這樣使得頁面跳轉功能很好的解耦,特別對於團隊開發有很好管理作用。
  2. 跨模塊頁面跳轉,模塊間解耦
  3. 處理登陸、埋點等邏輯
    說明:該場景使用到了路由監聽和攔截跳轉等功能,在原始處理登陸、埋點等功能中,我們會先初始化Activity,再進行邏輯判斷,這樣會影響性能,如果我們使用了監聽和攔截,那麼在初始化新的Activity之前,我們可以先進行邏輯判斷。

三、源碼下載

鏈接:https://pan.baidu.com/s/1Y7Br3iKlDb-55VG1kAU70A
提取碼:m0at

四、參考文章

    1. https://www.cnblogs.com/zhujiabin/p/7193400.html
    2. https://blog.csdn.net/x605940745/article/details/80583912
    3. https://blog.csdn.net/zhaoyanjun6/article/details/76165252

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、首先下載MySQL 推薦去官網上下載MySQL,如果不想找,那麼下麵就是: Windows32位地址:點擊這裡下載; Windows32位的MD5校驗碼: ae5f344fba95c12f097d338583b94a36; Windows64位地址:點擊這裡下載; Windows64位的MD5校 ...
  • 轉載來源:https://www.cnblogs.com/brianzhu/p/8575243.html 1. 下載並安裝MySQL官方的 Yum Repository 1 [root@BrianZhu /]# wget -i -c http://dev.mysql.com/get/mysql57- ...
  • 1.下載redis 下載地址 http://www.redis.cn/download.html 2.安裝redis 解壓 tar -zxvf redis-5.0.3.tar.gz $ cd redis-5.0.3 $ make 3.啟動redis $ cd src $ ./redis-server ...
  • 視圖DBA_OBJECTS記錄了資料庫中所有的對象,該視圖的OWNER是SYS 視圖描述如下: OWNER:對象的Owner OBJECT_NAME:對象名稱 SUBOBJECT_NAME:子對象名字,例如分區 OBJECT_ID:對象ID DATA_OBJECT_ID:包含該對象的段的字典對象數字 ...
  • 文章大綱 一、框架介紹 為什麼要用註解框架? 在Android開發過程中,我們經常性地需要操作組件,操作方法有findViewById, setOnClickListener等等方法,這個過程會讓工程師抓狂的,好在市面已經有大神封裝好的的註解框架可以幫助開發者簡化一些過程,下麵就讓我來給大家介紹一些 ...
  • ##文章大綱一、為什麼要使用日誌管理工具二、日誌管理工具實戰三、項目源碼下載 ##一、為什麼要使用日誌管理工具###1. 對IT安全至關重要&emsp;&emsp;當您使用強大的日誌管理軟體自動觸發以保護您的系統時,您已經贏得了一半的戰鬥,以確保您的IT基礎設施安全。某些日誌管理工具具有阻止可疑IP ...
  • 聲明周期 4種狀態 running / paused / stopped / killed 聲明周期 activity啟動 >onCreate() -->onStart() >onResume() 點擊Home鍵回到主界面(Activity不可見) -->onPause() --> onStop() ...
  • 文章大綱 一、webview基本介紹1.什麼是webview2.為什麼要使用webview3.webview基本操作 二、webview高級使用1.WebView狀態2.資源載入3.WebView載入優化4.數據緩存5.Android 和 JavaScript 交互6.網頁前進與後退7.記憶體管理8. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...