Android組件化最佳路由—ARetrofit

Android組件化最佳路由,為簡(jiǎn)單而生。

Github 源碼: ARetrofit

原文

demo

demo apk 下載

一 介紹

從命名來(lái)看,做Android開發(fā)的小伙伴們感覺(jué)是不是似曾相識(shí)…是的,Retrofit,一款優(yōu)秀的網(wǎng)絡(luò)框架,目前正在被大量使用,相信大家對(duì)它的用法已經(jīng)非常熟悉吧。

ARetrofit一款優(yōu)秀的Android組件化框架(皮一下_開心),可以輕松實(shí)現(xiàn)跨module通信。這里之所以使用Retrofit作為后綴命名主要是為了尊重retrofit大神的架構(gòu)思路,其目的降低開發(fā)者的學(xué)習(xí)和使用成本。

如果你正在對(duì)項(xiàng)目進(jìn)行組件化,ARetrofit將是不二選擇。

二 功能介紹

  • 新增ActivityCallback,通過(guò)配置一個(gè)參數(shù)實(shí)現(xiàn)Activity回調(diào),且可以回傳任意參數(shù),告別onActivityResult繁瑣寫法,使用更靈活
  • 支持直接解析標(biāo)準(zhǔn)URL進(jìn)行跳轉(zhuǎn)
  • 支持跨module通信
  • 支持添加多個(gè)攔截器,自定義攔截順序
  • 支持依賴注入,可單獨(dú)作為依賴注入框架使用
  • 可單獨(dú)作為自動(dòng)注冊(cè)框架使用
  • 支持InstantRun
  • 支持MultiDex(Google方案)
  • 頁(yè)面、攔截器、服務(wù)等組件均自動(dòng)注冊(cè)到框架
  • 支持獲取Fragment
  • 支持Kotlin混編
  • 跨進(jìn)程通信(待完善~)如有IPC業(yè)務(wù)可參考ABridge 進(jìn)程間通信最牛方案
    特點(diǎn):
    簡(jiǎn)單、低侵入(只需要在Activity/Fragment/其他類 聲明路由注冊(cè))、易上手

原理解析

二 基本用法

step1: 添加依賴和配置

  • project gradle file
buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:x.x.x'
        //自動(dòng)注入插件
        classpath "com.sjtu.yifei:auto-inject:1.0.1"
    }
}

  • app gradle file
//在plugin:'com.android.application'下添加以下插件,用于自動(dòng)注入
apply plugin: 'com.sjtu.yifei.autoinject'
  • lib module gradle file
dependencies {
   ...
   annotationProcessor "com.sjtu.yifei:auto-complier:1.5.0"

   api "com.sjtu.yifei:auto-api:1.5.0"
}
  • kotlin lib module gradle file
apply plugin: 'kotlin-kapt' //kotlin 需要添加插件

dependencies {
    ...
    //kotlin使用kapt插件
    kapt "com.sjtu.yifei:auto-complier:1.5.0"

    api "com.sjtu.yifei:auto-api:1.5.0"
}

step2: 聲明路由注解

  • Activity
/**
 * this activity in test-module1
 */
@Route(path = "/test-module1/Test1Activity")
public class Test1Activity extends AppCompatActivity {
    ...
}
  • Fragment
/**
 * this fragment in login-module
 */
@Route(path = "/login-module/TestFragment")
public class TestFragment extends Fragment {
    ...
}

step3: 面向接口編程:ARetrofit將Activity/Fragment 通信轉(zhuǎn)化成接口

/**
 * this interface in router-module
 */
public interface RouteService {
    //Activity 跳轉(zhuǎn),支持注解傳入?yún)?shù)/Flags/requestCode,參數(shù)解析遵循android機(jī)制
    @Flags(Intent.FLAG_ACTIVITY_NEW_TASK)
    @Go("/test-module1/Test1Activity")
    boolean launchTest1Activity(@Extra("para1") String para1, @Extra("para2") int para2);
    @Go("/test-module1/Test1Activity")
    boolean launchTest1ActivityForResult(@Extra("para1") String para1, @Extra("para2") int para2, @RequestCode int requestCode);

    //Fragment初始化,支持注解傳入?yún)?shù),參數(shù)解析遵循android機(jī)制
    @Go("/login-module/TestFragment")
    Fragment getTestFragment(@Extra("param1") String para1, @Extra("param2") int[] para2);
}

step4: 初始化SDK

    //在你的application onCreate()方法中
    Routerfit.init(this);

step5: 發(fā)起路由操作

private void launchTest1Activity(String para1, int para2) {
    //路由操作
   Routerfit.register(RouteService.class).launchTest1Activity(para1,para2);
}

step6:添加混淆規(guī)則(如果使用了Proguard)

-keep class * implements com.sjtu.yifei.ioc.**{*;}
-keep class * implements com.sjtu.yifei.annotation.AutoRegisterContract{*;}

三 支持ActivityCallback

告別onActivityResult,使得代碼更加簡(jiǎn)潔靈活,如登錄回調(diào)

step1:注冊(cè)登錄接口


public interface RouteService {
    ...
    //通過(guò)配置ActivityCallback參數(shù)實(shí)現(xiàn)Activity回調(diào)
    @Go("/login-module/LoginActivity")
    boolean launchLoginActivity(@Extra ActivityCallback callback);
}

step2:登錄回調(diào)操作(優(yōu)雅的實(shí)現(xiàn)登錄回調(diào))


@Interceptor(priority = 3)
public class LoginInterceptor implements AInterceptor {

    private static final String TAG = "LoginInterceptor";
    @Override
    public void intercept(final Chain chain) {
        //Test2Activity 需要登錄
        if ("/login-module/Test2Activity".equalsIgnoreCase(chain.path())) {
            Routerfit.register(RouteService.class).launchLoginActivity(new ActivityCallback() {
                @Override
                public void onActivityResult(int i, Object data) {
                    if (i == Routerfit.RESULT_OK) {//登錄成功后繼續(xù)執(zhí)行
                        Toast.makeText(ActivityLifecycleMonitor.getTopActivityOrApp(), "登錄成功", Toast.LENGTH_LONG).show();
                        chain.proceed();
                    } else {
                        Toast.makeText(ActivityLifecycleMonitor.getTopActivityOrApp(), "登錄取消/失敗", Toast.LENGTH_LONG).show();
                    }
                }
            });
        } else {
            chain.proceed();
        }
    }

}

四 高階用法

  • 以登錄組件為例

step1 聲明登錄服務(wù)

/**
 * this interface in router-module
 * 聲明登錄服務(wù)
 */
public interface ILoginProvider {
    String login();
}

注:#自己聲明的服務(wù)需要防止混淆#

-keep class * implements com.sjtu.yifei.route.ILoginProvider{*;}

step2 實(shí)現(xiàn)服務(wù)

/**
 * the ILoginProvider in login-module/
 */
@Route(path = "/login-module/ILoginProviderImpl")
public class ILoginProviderImpl implements ILoginProvider {

    private String para1;
    private int para2;

    public ILoginProviderImpl(String para1, int para2) {
        this.para1 = para1;
        this.para2 = para2;
    }

    @Override
    public String login() {
        Routerfit.register(RouteService.class).launchLoginActivity();
        return "ILoginProviderImpl para1:" + para1 + ",para2:" + para2;
    }
}

step3 注冊(cè)服務(wù)接口

public interface RouteService {
    ...
    //通過(guò)依賴注入解耦,支持注解傳入構(gòu)造函數(shù)參數(shù)
    @Go("/login-module/ILoginProviderImpl")
    ILoginProvider getILoginProviderImpl(@Extra("param1") String para1, @Extra("param2") int para2);
}

step4 攔截器功能

//攔截器只需申明注解,不需要額外處理。注:priority 值越大,攔截器優(yōu)先級(jí)越高
@Interceptor(priority = 3)
public class LoginInterceptor implements AInterceptor {

    private static final String TAG = "LoginInterceptor";

    @Override
    public void intercept(Chain chain) {
        Log.e(TAG,"path:" + chain.path());
        //假如 Test2Activity 需要登錄
        if ("/login-module/Test2Activity".equalsIgnoreCase(chain.path())) {
            if( /**是否需要登錄*/) {//需要登錄
                //獲取登錄服務(wù)
                ILoginProvider iProvider = Routerfit.register(RouteService.class).getILoginProviderImpl("provider from login-module", 10001);
                if (iProvider != null) {
                    iProvider.login();
                } else {
                    //傳遞請(qǐng)求,不執(zhí)行以下代碼則攔截請(qǐng)求
                    chain.proceed();
                }
            }
        } else {
            //傳遞請(qǐng)求,不執(zhí)行以下代碼則攔截請(qǐng)求
            chain.proceed();
        }
    }
}

五 歡迎 fork、issues

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容