Android模块化开发--路由ARouter日常使用

概述

公司基本上都是独立完成的小项目,所以模块化开发没接触过,本着学习的精神看到了ARouter路由觉得还不错,简单学习下,在这里当做记笔记了。

配置

在app moduel 下的build.gradle里添加:

 defaultConfig {
       ……
       ……
       //我添加的
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [ moduleName : project.getName() ]
            }
        }

    }
compile 'com.alibaba:arouter-api:1.2.1.1'
annotationProcessor 'com.alibaba:arouter-compiler:1.1.2.1'

tip:获取最新版本点我

日常使用

step.1

初始化操作:

if (isDebug()) {
    ARouter.openLog();     // 打印日志
    ARouter.openDebug();   // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
}
ARouter.init(mApplication); // 尽可能早,推荐在Application中初始化
step.2

2.1 目标Activity

@Route(path = "/login/activity_1")
public class LoginActivity_1 extends AppCompatActivity {}

2.2.1 发起路由操作(不带参数)

ARouter.getInstance()
                .build("/login/activity_1")
                .navigation();

2.2.2 发起路由操作(带参数,如果是对象且需要实现Parcelable接口)

 Bundle bundle = new Bundle();
        Entity entity = new Entity("唐人", "m1234");
        bundle.putParcelable("entity", entity);
        ARouter.getInstance()
                .build("/login/activity_1")
                .withBoolean("state", false)
                .withString("result", "123456")
                .withParcelable("entity", entity)
                .navigation();

2.3 目标Activity解析参数

2.3.1 使用原始getIntent()方式

 Entity entity = getIntent().getParcelableExtra("entity");
 boolean state = getIntent().getBooleanExtra("state",false);
 ……
 ……

2.3.2 使用ARouter协助解析参数类型

@Route(path = "/login/activity_1")
public class LoginActivity_1 extends AppCompatActivity {

    @Autowired
    public boolean state;//变量名与传参时一致且修饰符为public
    @Autowired
    public String result;
    @Autowired
    public Entity entity;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ARouter.getInstance().inject(this);
        TextView view = (TextView) findViewById(R.id.title);
        view.setText(state + "\n" + result + "\n" + entity.toString());
    }
}
step.3

声明拦截器,拦截器会在跳转之间执行,多个拦截器会按优先级顺序依次执行,init只在sdk初始化的时候才被调用仅1次

@Interceptor(priority = 100, name = "LoginCheck")
public class MyIInterceptor implements IInterceptor {
    @Override
    public void process(Postcard postcard, InterceptorCallback callback) {
        switch (postcard.getPath()) {
            case "/login/activity_1":
                if (postcard.getExtras().getString("name").equals("wuxinxi"))
                    callback.onContinue(postcard);
                else callback.onInterrupt(new RuntimeException("用户名不对哦"));
                break;
            default:
                if (postcard.getExtra()==-100){
                    callback.onInterrupt(new RuntimeException("我看你不顺眼"));
                }
                callback.onContinue(postcard);
                break;
        }
    }

    @Override
    public void init(Context context) {
        System.out.println("拦截器被初始化");
    }
}
step.4

通过Uri跳转
4.1 系统原生的方式:

  <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
                <data
                    android:host="www.ccc"
                    android:port="80"
                    android:path="/app_name"
                    android:scheme="tangren" />
                <action android:name="com.tangren" />
   </intent-filter>

java代码:

        Intent intent = new Intent();
        Uri uri = Uri
                .parse("tangren://www.ccc:80/app_name");
        intent.setData(uri);
        intent.setAction("com.tangren");
        try {
            startActivity(intent);
        } catch (Exception e) {
            Toast.makeText(this, "找不到目标Activity", Toast.LENGTH_SHORT).show();
        }

tip:
1.包含在 标签对里,而且是必不可少的!不管以哪一种方式来匹配,都不可缺少这个 ,可以有多个,至少要有一个,在代码中匹配data时可不匹配action也可启动目标Activity;
2.data中不能同时存在mineType、scheme;
3.根据action和data的mimeType属性匹配时,单靠data的mimeType属性不能匹配,就算这个mimeType是唯一的也不行,必须配合一个action ;
4.一个Activity里可以有多对 只要匹配其中一对,即可启动这个Activity
5. 任何一个需要隐式启动的Activity都必须要有这项:<category android:name="android.intent.category.DEFAULT"/> 例外情况是:android.intent.category.MAIN和android.intent.category.LAUNCHER的filter中没有必要加入android.intent.category.DEFAULT,当然加入也没有问题
6. 当匹配不上任何Activity的话,会发生异常,记得捕获异常

4.2 ARouter

 <intent-filter>
                <data
                    android:host="com.tangren"
                    android:scheme="tangren"/>
                <action android:name="com.tangren.action"/>
 </intent-filter>

java代码

        Uri uri = Uri
                .parse("tangren://com.tangren/login/activity_2");
        ARouter.getInstance()
                .build(uri)
                .navigation();

html代码

<a href="tangren://com.tangren/login/activity_2">跳转</a>
step.5

传递自定义对象点我

step.6

处理跳转结果

        Uri uri = Uri
                .parse("tangren://com.tangren/login/activity_2");
        ARouter.getInstance()
                .build(uri)
                .navigation(this, new NavigationCallback() {
                    @Override
                    public void onFound(Postcard postcard) {
                        Toast.makeText(MainActivity.this, "发现目标Activity", Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onLost(Postcard postcard) {
                        Toast.makeText(MainActivity.this, "没有目标Activity", Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onArrival(Postcard postcard) {
                        Toast.makeText(MainActivity.this, "跳转完成", Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onInterrupt(Postcard postcard) {
                        Toast.makeText(MainActivity.this, "已被拦截", Toast.LENGTH_SHORT).show();
                    }
                });

step.7

降级策略点我

step.8

为目标页面声明更多信息

// 我们经常需要在目标页面中配置一些属性,比方说"是否需要登陆"之类的
// 可以通过 Route 注解中的 extras 属性进行扩展,这个属性是一个 int值,换句话说,单个int有4字节,也就是32位,可以配置32个开关
// 剩下的可以自行发挥,通过字节操作可以标识32个开关,通过开关标记目标页面的一些属性,在拦截器中可以拿到这个标记进行业务逻辑判断
@Route(path = "/login/activity_3", extras = -100)

拦截器判断

                if (postcard.getExtra()==-100){
                    callback.onInterrupt(new RuntimeException("我看你不顺眼"));
                }
step.9

9.1 通过依赖注入解耦:服务管理-暴露服务
9.2 通过依赖注入解耦:服务管理-发现服务
详情点我

step.10

更多功能
10.1 初始化中的其他设置

ARouter.openLog(); // 开启日志
ARouter.openDebug(); // 使用InstantRun的时候,需要打开该开关,上线之后关闭,否则有安全风险
ARouter.printStackTrace(); // 打印日志的时候打印线程堆栈

10.2 详细的API说明

// 构建标准的路由请求
ARouter.getInstance().build("/home/main").navigation();

// 构建标准的路由请求,并指定分组
ARouter.getInstance().build("/home/main", "ap").navigation();

// 构建标准的路由请求,通过Uri直接解析
Uri uri;
ARouter.getInstance().build(uri).navigation();

// 构建标准的路由请求,startActivityForResult
// navigation的第一个参数必须是Activity,第二个参数则是RequestCode
ARouter.getInstance().build("/home/main", "ap").navigation(this, 5);

// 直接传递Bundle
Bundle params = new Bundle();
ARouter.getInstance()
    .build("/home/main")
    .with(params)
    .navigation();

// 指定Flag
ARouter.getInstance()
    .build("/home/main")
    .withFlags();
    .navigation();

// 获取Fragment
Fragment fragment = (Fragment) ARouter.getInstance().build("/test/fragment").navigation();

// 对象传递
ARouter.getInstance()
    .withObject("key", new TestObj("Jack", "Rose"))
    .navigation();

// 觉得接口不够多,可以直接拿出Bundle赋值
ARouter.getInstance()
        .build("/home/main")
        .getExtra();

// 转场动画(常规方式)
ARouter.getInstance()
    .build("/test/activity2")
    .withTransition(R.anim.slide_in_bottom, R.anim.slide_out_bottom)
    .navigation(this);

// 转场动画(API16+)
ActivityOptionsCompat compat = ActivityOptionsCompat.
    makeScaleUpAnimation(v, v.getWidth() / 2, v.getHeight() / 2, 0, 0);

// ps. makeSceneTransitionAnimation 使用共享元素的时候,需要在navigation方法中传入当前Activity

ARouter.getInstance()
    .build("/test/activity2")
    .withOptionsCompat(compat)
    .navigation();

// 使用绿色通道(跳过所有的拦截器)
ARouter.getInstance().build("/home/main").greenChannel().navigation();

// 使用自己的日志工具打印日志
ARouter.setLogger();

10.3 获取原始的URI

String uriStr = getIntent().getStringExtra(ARouter.RAW_URI);

10.4 重写跳转URL

// 实现PathReplaceService接口,并加上一个Path内容任意的注解即可
@Route(path = "/xxx/xxx") // 必须标明注解
public class PathReplaceServiceImpl implements PathReplaceService {
    /**
     * For normal path.
     *
     * @param path raw path
     */
    String forString(String path) {
    return path;    // 按照一定的规则处理之后返回处理后的结果
    }

   /**
    * For uri type.
    *
    * @param uri raw uri
    */
   Uri forUri(Uri uri) {
    return url;    // 按照一定的规则处理之后返回处理后的结果
   }
}

感谢

https://github.com/alibaba/ARouter

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吴唐人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值