ARouter簡單入門和介紹

1.路由介紹

什麼是路由框架?java

說簡單點就是映射頁面跳轉關係的,固然它也包含跳轉相關的一切功能android

爲何使用ARouter?git

咱們先從適用場景來分析:github

  1. 動態跳轉:通常來講複雜的電商跳轉多頁面須要很強的靈活性,不少狀況下是運營人員動態配置的下發活動頁面,須要靈活的進行跳轉。編程

  2. 組件化:隨着業務量的不斷增加,app也會不斷的膨脹,開發團隊的規模和工做量也會逐漸增大,面對所衍生的64K問題、協做開發問題等,app通常都會走向組件化。組件化就是將APP按照必定的功能和業務拆分紅多個組件module,不一樣的組件獨立開發,組件化不只可以提供團隊的工做效率,還可以提升應用性能。而組件化的前提就是解耦,那麼咱們首先要作的就是解耦頁面之間的依賴關係json

  3. Native與H5的問題:如今的APP不多是純Native的,也不多會有純H5的,通常狀況下都是將二者進行結合。這時候就須要很是便捷而且統一的跳轉方案,由於在H5中是沒法使用StartActivity()跳轉到Native頁面的,而從Native跳轉到H5頁面也只能經過配置瀏覽器的方式實現api

  4. 其餘等場景瀏覽器

原生跳轉方式的不足安全

  • 顯式跳轉, Intent intent = new Intent(activity, XXActivity.class);
    因爲須要直接持有對應class,從而致使了強依賴關係,提升了耦合度bash

  • 隱式跳轉,譬如 Intent intent = new Intent(); intent.setAction(「com.android.activity.MY_ACTION」);
    action等屬性的定義在Manifest,致使了擴展性較差
    規則集中式管理,致使協做變得很是困難。

  • 原生的路由方案會出現跳轉過程沒法控制的問題,由於一旦使用了StartActivity()就沒法插手其中任何環節了,只能交給系統管理,這就致使了在跳轉失敗的狀況下沒法降級,而是會直接拋出運行時的異常。

2.ARouter的使用

1.添加框架的依賴和配置

在各個模塊的build.gradle中添加編譯參數和依賴的框架

android {
    defaultConfig {
    ...
    javaCompileOptions {
        annotationProcessorOptions {
        arguments = [ moduleName : project.getName() ]
        }
    }
    }
}

dependencies {
    // 替換成最新版本, 須要注意的是api
    // 要與compiler匹配使用,均使用最新版能夠保證兼容
    compile 'com.alibaba:arouter-api:1.2.2'
    annotationProcessor 'com.alibaba:arouter-compiler:1.1.3'
    ...
}

// 舊版本gradle插件(< 2.2),可使用apt插件,在根build.gradle中配置方法
apply plugin: 'com.neenbedankt.android-apt'

buildscript {
    repositories {
        jcenter()    
    }

    dependencies {
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    }
}複製代碼

2.添加註解

// 在支持路由的頁面上添加註解(必選)
// 這裏的路徑須要注意的是至少須要有兩級,/xx/xx
@Route(path = "/test/activity")
public class YourActivity extend Activity {
    ...
}複製代碼

3.初始化SDK

if (isDebug()) {           // 這兩行必須寫在init以前,不然這些配置在init過程當中將無效
    ARouter.openLog();     // 打印日誌
    ARouter.openDebug();   // 開啓調試模式(若是在InstantRun模式下運行,必須開啓調試模式!線上版本須要關閉,不然有安全風險)
}
ARouter.init(mApplication); // 儘量早,推薦在Application中初始化複製代碼

4.路由操做

// 1.普通跳轉
ARouter.getInstance().build("/test/activity").navigation();

// 2.跳轉並攜帶參數
ARouter.getInstance().build("/test/activity2").navigation();
// 3.跳轉並攜帶請求碼
ARouter.getInstance().build("/test/activity2").navigation(this, requestCode);

// 4.URI跳轉 
/*這種使用URi的方式中,URi的Scheme 和 host不影響結果,能夠隨便設,關鍵的是path
*  - build(URI)會把URI解析爲path,並把當前URI存入PostCard
*  - build(String)構造的PostCard不存儲URI*/
Uri testUriMix = Uri.parse("xx://xxx/test/activity2");
ARouter.getInstance().build(testUriMix)
                        .withString("name", "老王")
                        .withInt("age", 18)
                        .withBoolean("boy", true)
                        .withLong("high", 180)
                        .withString("url", "https://a.b.c")
                        .withParcelable("pac", testParcelable)
                        .withObject("obj", testObj)
                        .navigation();

// 5.跳轉包含回調 單次降級策略能夠在這裏使用
ARouter.getInstance().build("/test/activity2").navigation(Context mContext, int requestCode, NavigationCallback callback);複製代碼

5.配置自定義序列化方式

上訴的代碼中有withObject進行傳參,沒有定義序列化方式是沒法進行解析所以須要定義一個序列化方式,如下采用FastJson進行序列化

// 若是須要傳遞自定義對象,須要實現 SerializationService,並使用@Route註解標註(方便用戶自行選擇序列化方式),例如:
@Route(path = "/service/json")
public class JsonServiceImpl implements SerializationService {
    @Override
    public void init(Context context) {

    }

    @Override
    public <T> T json2Object(String text, Class<T> clazz) {
        return JSON.parseObject(text, clazz);
    }

    @Override
    public String object2Json(Object instance) {
        return JSON.toJSONString(instance);
    }
}複製代碼

6.聲明攔截器(攔截跳轉過程,面向切面編程)

// 比較經典的應用就是在跳轉過程當中處理登錄事件,這樣就不須要在目標頁重複作登錄檢查
// 攔截器會在跳轉之間執行,多個攔截器會按優先級順序依次執行
@Interceptor(priority = 8, name = "測試用攔截器")
public class TestInterceptor implements IInterceptor {
    @Override
    public void process(Postcard postcard, InterceptorCallback callback) {
    ...
    callback.onContinue(postcard);  // 處理完成,交還控制權
    // callback.onInterrupt(new RuntimeException("我以爲有點異常"));      // 以爲有問題,中斷路由流程

    // 以上兩種至少須要調用其中一種,不然不會繼續路由
    }

    @Override
    public void init(Context context) {
    // 攔截器的初始化,會在sdk初始化的時候調用該方法,僅會調用一次
    }
}複製代碼

// 咱們常常須要在目標頁面中配置一些屬性,比方說"是否須要登錄"之類的
// 能夠經過 Route 註解中的 extras 屬性進行擴展,這個屬性是一個 int值,換句話說,單個int有4字節,也就是32位,能夠配置32個開關
// 剩下的能夠自行發揮,經過字節操做能夠標識32個開關,經過開關標記目標頁面的一些屬性,在攔截器中能夠拿到這個標記進行業務邏輯判斷
@Route(path = "/test/activity", extras = Consts.XXXX)

7.經過依賴注入解耦:服務管理(一) 暴露服務

// 聲明接口,其餘組件經過接口來調用服務
public interface HelloService extends IProvider {
    String sayHello(String name);
}

// 實現接口
@Route(path = "/service/hello", name = "測試服務")
public class HelloServiceImpl implements HelloService {

    @Override
    public String sayHello(String name) {
    return "hello, " + name;
    }

    @Override
    public void init(Context context) {

    }
}複製代碼

8.經過依賴注入解耦:服務管理(二) 發現服務

public class Test {
    @Autowired
    HelloService helloService;

    @Autowired(name = "/service/hello")
    HelloService helloService2;

    HelloService helloService3;

    HelloService helloService4;

    public Test() {
    ARouter.getInstance().inject(this);
    }

    public void testService() {
     // 1. (推薦)使用依賴注入的方式發現服務,經過註解標註字段,便可使用,無需主動獲取
     // Autowired註解中標註name以後,將會使用byName的方式注入對應的字段,不設置name屬性,會默認使用byType的方式發現服務(當同一接口有多個實現的時候,必須使用byName的方式發現服務)
    helloService.sayHello("Vergil");
    helloService2.sayHello("Vergil");

    // 2. 使用依賴查找的方式發現服務,主動去發現服務並使用,下面兩種方式分別是byName和byType
    helloService3 = ARouter.getInstance().navigation(HelloService.class);
    helloService4 = (HelloService) ARouter.getInstance().build("/service/hello").navigation();
    helloService3.sayHello("Vergil");
    helloService4.sayHello("Vergil");
    }複製代碼

小結

官方的文檔Github很詳細能夠去看看

以上方式能夠進行簡單的入門使用了,下一步咱們從源碼分析。

相關文章
相關標籤/搜索