Arouter入门篇

    Aouter的一款由Ali团队开发的Android路由框架,本文旨在讲解Arouter官方网站的Demo,而不是自己的Demo,因为我觉得官方的Demo已经足够满足开发的业务需求,就不必自己再轮一篇,本文是对文档的一些补充。

官方地址

git clone https://github.com/alibaba/ARouter.git 神传送下载源码

我们先来闲聊下我们项目中可能用到的跳转业务功能:

1、Activity跳转,并传参数(参数包括基本类型和引用类型)

2、Fragment跳转,并传参数(参数包括基本类型和引用类型)

3、我想在跳转的时候做点判断和控制什么的,甚至是拦截一些界面不给没有权限的用户访问等需求

4、我想解耦,不依赖某个Activity的引用

        以上四点基本满足我们对跳转的需求,但是原生我们无法拦截界面的跳转,1、2点倒是可以实现,但是重复性劳动非常大,而且显示跳转的时候,依赖跳转之后的Activity.class ,这使得我们在并行开发的时候非常被动,如果使用隐式跳转,当Activity不存在的时候又会崩溃,所以基于以上考虑,我不得不引入一个路由框架,进行对Aouter的进行调研后和阅读关键性源码后,决定使用这个框架进行开发。

提供下刘志龙大神对Arouter的架构和原理进行讲解概况地址,大家有兴致可以看下:

点击打开链接  

集成Aouter

Aouter Api包括三种类型:

api :com.alibaba:arouter-api:x.x.x

注解器:com.alibaba:arouter-compiler:x.x.x

        自动注册插件:com.alibaba:arouter-register:x.x.x

    (以目前最新版本为列)在app的build.gradle里面添加:

    

android {
    defaultConfig {
	...
	javaCompileOptions {
	    annotationProcessorOptions {
		arguments = [ moduleName : project.getName() ]
	    }
	}
    }
}
dependencies {
    // 替换成最新版本, 需要注意的是api
    // 要与compiler匹配使用,均使用最新版可以保证兼容
    compile 'com.alibaba:arouter-api:1.3.1'
    annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'
}

如果AndroidStudio 3.0  gradle插件3.0 以上 compile 使用 api替换

如果gradle插件少于2.2的版本 annotationProcessor需要使用apt插件替换

如果是Kotlin项目,请使用k-apt插件替换 

kotilin配置列子:

项目层的build.gradle,添加插件:

buildscript {
    ext.kotlin_version = '1.1.3-2'
    dependencies {
      classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

app层的build.gradle:

apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
dependencies {
    kapt 'com.alibaba:arouter-compiler:1.0.3'
}

注:假如是组件化项目需要注意 javaCompileOptions和 annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'每个组件的配置都需要有 ,api可以放在基础库中。

配置自动注册插件,在项目层的build.gradle:

  dependencies {
        classpath 'com.alibaba:arouter-register:1.0.2'
    }

版本api 1.3.1对应1.0.2  搞错了无效。


基础概念

    注解:

    1、@Route  路由注解。 定义一个可以找到某个目标的字符串,用于Activity、Fragment、Service的路径。

    path:路径字符串 比如“test/activity1”

    注意:path新版必须设置一个“XXX/XXX”斜杠的类型,因为一个斜杠之前的字符串作为一个组

    group:组,新版本不建议使用

    name:定义路径的名字,默认为 “undefined”。用来添加注释

    priority:优先级 默认为-1。

    extras :额外的数据,Interget类型,可以用来控制目标页面的业务逻辑,比如1 or 0表示某个页面是否展示,把他当前2禁止的时候可以控制32个业务开关。一般不常用。

    2、@Interceptor  定义拦截器,添加该注释可以定义一个全局Activity跳转的拦截器。

    priority:优先级

    name:默认Default

    3、@Autowired 注入参数,用于接收传送参数 或者 注入Service

    name:参数名,默认""

    required:是否必须,如果为true, 数据为null的话会导致app崩溃

    desc:对参数进行描述 相当于注释

初始化

    

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

Activity跳转

    简单的Activity跳转:

    使用Router定义路径

@Route(path = "/test/activity1")
public class Test1Activity extends AppCompatActivity {

    跳转

ARouter
.getInstance()
.build("/test/activity1").navigation();
   

    带基础参数的Activity

    跳转

 ARouter.getInstance()
          .build("/test/activity2")
          .withString("key1", "value1")
          .navigation();

    withXX (key,value)传送的是基本类型,可以通过key接收到这个数据

     使用withObject(key,value)传送自定义对象,使用自定义对象要实现SerializationService接口,并且规定路由设置成@Route(path = "/service/json") 。比如使用FastJSON进行序列化:

@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);
    }
}

    Parcelable和Serializable对象传输是直接支持的。

    

    接收数据的时候有两种方式

    一种是原生使用的接收方式

 String value = getIntent().getXXXExtra("key");

    另一种是使用注释获取到,先在Activity中添加 ARouter.getInstance().inject(this);

@Autowired(name="key")
String key;

    通过name来匹配,默认通过类型匹配。

   需要返回的Activity跳转

    

ARouter.getInstance()
       .build("/test/activity2")
       .navigation(this, 666);
setResult(666);
 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        switch (requestCode) {
            case 666:
                Log.e("activityResult", String.valueOf(resultCode));
                break;
            default:
                break;
        }
    }

 自定义协议跳转的Activity

    定义协议:

 
 
<activity android:name=".SchemeFilterActivity">
            <!-- Schame -->
            <intent-filter>
                <data
                    android:host="m.aliyun.com"
                    android:scheme="arouter"/>

                <action android:name="android.intent.action.VIEW"/>

                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>
      
        </activity>

其中scheme定义协议头,可以随便自己定制,m.aliun.com是host

 当我们跳转的时候需要一个中间者进行调度,如:SchemeFilterActivity就是用来对协议进行中间调度的

public class SchemeFilterActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

//        直接通过ARouter处理外部Uri
        Uri uri = getIntent().getData();
        ARouter.getInstance().build(uri).navigation(this, new NavCallback() {
            @Override
            public void onArrival(Postcard postcard) {
                finish();
            }
        });
    }
}

我们想要跳转时,可以这样, 比如需要跳转到 test/activity2

 Uri testUriMix = Uri.parse("arouter://m.aliyun.com/test/activity2");
                ARouter.getInstance().build(testUriMix)
                        .withString("key1", "value1")
                        .navigation();

上面的SchemeFilterActivity只是一个中间调度,不是我们的目标Activity,我们的目标activity是 test/activity2,Uri需要这样拼接:协议字符串+目标跳转的路径。

当SchemeFilterActivity接收到uri后再进行一次跳转,从SchemeFilterActivity中取出来的getIntent().getData()==" test/activity2"。

我们还可以在网页直接跳转到应用内的activity,在SchemeFilterActivity清单文件中 intent-filter添加Links

 <intent-filter android:autoVerify="true">
                <action android:name="android.intent.action.VIEW"/>

                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>

                <data
                    android:host="m.aliyun.com"
                    android:scheme="http"/>
                <data
                    android:host="m.aliyun.com"
                    android:scheme="https"/>
            </intent-filter>

html中使用标签<a></a>

<a href="arouter://m.aliyun.com/test/activity3?name=alex&age=18&boy=true&high=180">arouter://m.aliyun.com/test/activity3?name=alex&age=18&boy=true&high=180</a>
后面?之后是传参数。相当于一个get请求一样。

跳转监听器回调NavCallback

    

 ARouter.getInstance().build("/xxx/xxx").navigation(this, new NavCallback() {
                    @Override
                    public void onFound(Postcard postcard) {
                        Log.d("ARouter", "找到了");
                    }

                    @Override
                    public void onLost(Postcard postcard) {
                        Log.d("ARouter", "找不到了");
                    }

                    @Override
                    public void onArrival(Postcard postcard) {
                        Log.d("ARouter", "跳转完了");
                    }

                    @Override
                    public void onInterrupt(Postcard postcard) {
                        Log.d("ARouter", "被拦截了");
                    }
                });

使用NavCallback进行监听跳转过程中是否被拦截,或者是否完成跳转。比如我们可以在跳转后进行一些保存数据的操作,当没有发现Activity的时候提示模块未开放等功能。

转场动画

跳转动画在Arouter里面实现也很简单,只需要定义好出入的动画然后调用如下:

ARouter.getInstance()
    .build("/test/activity2")
    .withTransition(R.anim.slide_in_bottom, R.anim.slide_out_bottom)
    .navigation(this);
很多时候大家都会问,为什么设置了无效,这可能并不是Arouter的问题,而是因为你的样式为了不出现黑屏设置了 android:windowIsTranslucent为true导致的。

共享元素的转场动画

             if (Build.VERSION.SDK_INT >= 16) {
                    ActivityOptionsCompat compat = ActivityOptionsCompat.
                            makeScaleUpAnimation(v, v.getWidth() / 2, v.getHeight() / 2, 0, 0);
                    ARouter.getInstance()
                            .build("/test/activity2")
                            .withOptionsCompat(compat)
                            .navigation();
                } else {
                    ARouter.getInstance()
                            .build("/test/activity2")
                            .navigation();
                }
因为只有API大于16才支持共享元素,所以当少于16的时候我们直接跳转。

获取Fragment

添加路由:

@Route(path = "/test/fragment")
public class BlankFragment extends Fragment

带参数的跳转

未完待续。。。



    

猜你喜欢

转载自blog.csdn.net/u010782846/article/details/80205317