1. 程式人生 > >Android開發的簡易路由框架

Android開發的簡易路由框架

EasyRouter

erouter erouter-compiler erouter-anno

EasyRouter是專門針對Android開發的簡易路由框架,支援路由分組,使用方便,功能全面。主要包含三大模組功能:路由轉發、自動注入和路由攔截。

專案地址

功能簡介

  • 簡單路由轉發
  • 多模組之間路由轉發
  • 支援MultiDexInstantRun
  • 引數自動注入
  • 路由攔截

效果展示

  • 效果圖:

    screenshot

  • Demo下載:

    download

基本用法

包括路由轉發、自動注入和路由攔截。

新增依賴

在專案主模組中新增如下依賴

dependencies {
  compile 'com.yhy.router:erouter:latestVersion'
annotationProcessor 'com.yhy.router:erouter-compiler:latestVersion' }

初始化

Application中進行初始化

@Override
public void onCreate() {
  super.onCreate();

  // 初始化
  ERouter.getInstance()
    .init(this)
    .log(BuildConfig.DEBUG)
    .jsonParser(new EJsonParser() {
      Gson gson = new Gson();
      @Override
public <T> T fromJson(String json, Class<T> clazz) { return gson.fromJson(json, clazz); } @Override public <T> String toJson(T obj) { return gson.toJson(obj); } }); }

給需要路由轉發的物件註冊路由

  • 普通路由

    ActivityFragmentService用法都相同

    @Router
    (url = "/activity/normal") public class NormalActivity extends BaseActivity { } @Router(url = "/fragment/normal") public class NormalFragment extends BaseFragment { } @Router(url = "/service/normal") public class NormalService extends BaseService { }
  • 分組路由

    支援路由分組,不指定分組時預設按路由的一級路徑分組

    @Router(url = "/activity/group", group = "acgp")
    public class GroupActivity extends BaseActivity {
    }
  • 自動注入引數路由

    支援引數欄位自動注入,包括私有成員

    注:如果不手動設定引數名的話,需要保持這裡的欄位名和設定引數時的引數名相同

    使用自動注入引數時不推薦private修飾(私有成員通過反射注入)

    @Router(url = "/activity/autowried")
    public class AutowiredActivity extends BaseActivity {
    @Autowired
    public String defParam;
    @Autowired("changed")
    public String chgParam;
    @Autowired
    public User objParam;
    @Autowired
    private String privParam;
    @Autowired
    private User privObjParam;
    @Autowired
    public SeriaEntity seriaParam;
    
    // 不自動注入
    private String param;
    
    private TextView tvDef;
    private TextView tvChg;
    private TextView tvObj;
    private TextView tvPriv;
    private TextView tvPrivObj;
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
      // 注入當前物件,觸發自動注入操作
      ERouter.getInstance().inject(this);
      super.onCreate(savedInstanceState);
    }
    
    @Override
    protected int getLayout() {
      return R.layout.activity_autowired;
    }
    
    @Override
    protected void initView() {
      tvDef = $(R.id.tv_def);
      tvChg = $(R.id.tv_chg);
      tvObj = $(R.id.tv_obj);
      tvPriv = $(R.id.tv_priv);
      tvPrivObj = $(R.id.tv_priv_obj);
      tvPrivSeria = $(R.id.tv_priv_seria);
    }
    
    @Override
    protected void initData() {
      tvDef.setText("預設引數:" + defParam);
      tvChg.setText("改變過引數:" + chgParam);
      tvObj.setText("物件引數:" + objParam.toString());
      tvPriv.setText("私有成員引數:" + privParam);
      tvPrivObj.setText("私有物件引數:" + privObjParam.toString());
      tvPrivSeria.setText("Serializable物件引數:" + seriaParam.toString());
    }
    }
  • Fragment路由轉發

    目前不支援直接跳轉Fragment,路由只是獲取到確定的Fragment例項,然後需要手動通過事務設定Fragment顯示

    為了方便起見,這裡使用了一個Fragment簡易開源庫:FragmentHelper

    FmHelper helper = new FmHelper.Builder(this, R.id.fl_content).build();
    Fragment fm = ERouter.getInstance().with(this).to("/fragment/v4/normal").go();
    helper.open(fm);

路由轉發

  • 普通路由

    ERouter.getInstance()
    .with(MainActivity.this)
    .to("/activity/normal")
    .go();
  • 分組路由

    ERouter.getInstance()
    .with(MainActivity.this)
    .to("acgp", "/activity/group")
    .go();
  • 帶參自動注入轉發

    注:如果目標中不手動設定引數名的話,需要保持設定的引數名與目標成員欄位名相同

    ERouter.getInstance()
    .with(MainActivity.this)
    .to("/activity/autowried")
    .param("defParam", "預設名稱引數")
    .param("changed", "修改過名稱引數")
    .param("objParam", new User("張三", 25, "男"))
    .param("privParam", "private引數")
    .param("privObjParam", new User("李四", 33, "女"))
    .param("seriaParam", new SeriaEntity("test-test"))
    .go();
  • 帶攔截器路由轉發

    路由新增攔截器,執行順序與設定順序一致

    攔截器名稱與@Interceptor註解的名稱一致,不設定名稱時預設使用攔截器類名

    如果中間某個攔截器中斷了路由,操作將會被中斷

    // 多個攔截器按設定順序執行
    ERouter.getInstance()
    .with(MainActivity.this)
    .to("/activity/interceptor")
    .interceptor("login")
    .interceptor("LastInterceptor")
    .go();
  • Activity切換動畫

    ERouter.getInstance()
    .with(MainActivity.this)
    .to("/activity/transition")
    .transition(R.anim.slide_in_right, R.anim.slide_out_right)
    .go();
  • Activity共享元素動畫

    ERouter.getInstance()
    .with(MainActivity.this)
    .to("/activity/make/anim")
    .animate("tvAnim", view)
    .go();
  • Service中開啟Activity

    這裡主要說明針對Intentflag方法

    ERouter.getInstance()
    .with(this)
    .to("/activity/service")
    .flag(Intent.FLAG_ACTIVITY_NEW_TASK) // Service跳轉Activity時最好加上改flag
    .go();
  • 根據Uri開啟Activity

    設定Uri後,不在根據Url跳轉,切目標只能是Activity。不過設定引數、flag等功能還是支援的

    ERouter.getInstance()
    .with(MainActivity.this)
    .uri(Uri.parse("http://www.baidu.com"))
    .action(Intent.ACTION_VIEW)
    .transition(R.anim.slide_in_right, R.anim.slide_out_right)
    .go(mCallback); // 設定回撥

定義攔截器

實現EInterceptor介面,在execute(EPoster poster)方法中完成攔截操作

注:預設返回false,表示不中斷路由,如需要中斷路由操作返回true即可

@Interceptor(name = "login")// 不指定名稱時攔截器將以類名作為名稱
public class LoginInterceptor implements EInterceptor {

  @Override
  public boolean execute(EPoster poster) {
    // 攔截登入狀態
    User user = App.getInstance().getUser();
    if (null == user) {
      Toast.makeText(poster.getContext(), "未登入,先去登入", Toast.LENGTH_SHORT).show();

      // 跳轉到登入頁面
      ERouter.getInstance()
        .with(poster.getContext())
        .to("/activity/login")
        .go();

      // 返回true表示中斷原本的路由
      return true;
    }

    Toast.makeText(poster.getContext(), "已經登入,往下執行", Toast.LENGTH_SHORT).show();
    // 返回false表示繼續往下執行
    return false;
  }
}

That's all, enjoy it !!!