Android开发的简易路由框架

EasyRouter

EasyRouter是专门针对Android开发的简易路由框架,支持路由分组,使用方便,功能全面。主要包含三大模块功能:路由转发、自动注入和路由拦截。

项目地址

Github地址:EasyRouter

功能简介

  • 简单路由转发
  • 多模块之间路由转发
  • 支持MultiDexInstantRun
  • 参数自动注入
  • 路由拦截

效果展示

  • 效果图:

  • Demo下载:

基本用法

包括路由转发、自动注入和路由拦截。

添加依赖

在项目主模块中添加如下依赖

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 fromJson(String json, Class clazz) {
        return gson.fromJson(json, clazz);
      }

      @Override
      public  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 !!!

你可能感兴趣的:(Android,框架)