Android路由框架-ARouter详解(非原创)

文章大纲

1、页面路由基本介绍
1.什么是页面路由
2.为何要使用页面路由
2、页面路由框架ARouter介绍
1.经常使用功能介绍
2.常见应用场景
3、源码下载
4、参考文章javascript

 

1、页面路由基本介绍

1.什么是页面路由

  映射页面跳转关系,包含跳转相关的URL跳转及值传递、拦截器等功能。css

2.为何要使用页面路由

  在原始android开发中,当咱们须要进行页面跳转时,正常写法以下:html

Intent intent = new Intent(mContext, XXActivity.class); intent.putExtra("key","value"); startActivity(intent); Intent intent = new Intent(mContext, XXActivity.class); intent.putExtra("key","value"); startActivityForResult(intent, 100); 

上述写法容易出现如下问题:java

  1. 多人协同开发的时候,你们都去AndroidManifest.xml中定义各类IntentFilter,使用隐式Intent,最终发现AndroidManifest.xml中充斥着各类Schame,各类Path,须要常常解决Path重叠覆盖、过多的Activity被导出,引起安全风险等问题
  2. 跳转过程当中没法插手:直接经过Intent的方式跳转,跳转过程开发者没法干预,一些面向切面的事情难以实施,比方说登陆、埋点这种很是通用的逻辑,在每一个子页面中判断又很不合理,毕竟activity已经实例化了
  3. 跨模块没法显式依赖:在App小有规模的时候,咱们会对App作水平拆分,按照业务拆分红多个子模块,之间彻底解耦,经过打包流程控制App功能,这样方便应对大团队多人协做,互相逻辑不干扰,这时候只能依赖隐式Intent跳转,书写麻烦,成功与否难以控制

页面路由能够解决什么问题?android

 

 

2、页面路由框架ARouter介绍

1.经常使用功能介绍

应用内页面跳转web

添加依赖api

 

舒适提示:api 的版本和 compiler 的版本号须要用最新的。最新的版本在 Github上能够找到。数组

重写Application并初始化ARouter安全

 
 

配置将要跳转的页面bash

 

进行简单的页面跳转

 

 

舒适提示:若是你想实现像 startActivityForResult() 功能,能够这样使用

 

运行结果以下:

 
 

携带参数进行页面跳转

 

舒适提示:支持数据类型以下:

//基础类型 .withString( String key, String value ) .withBoolean( String key, boolean value) .withChar( String key, char value ) .withShort( String key, short value) .withInt( String key, int value) .withLong( String key, long value) .withDouble( String key, double value) .withByte( String key, byte value) .withFloat( String key, float value) .withCharSequence( String key, CharSequence value) //数组类型 .withParcelableArrayList( String key, ArrayList<? extends Parcelable > value) .withStringArrayList( String key, ArrayList<String> value) .withIntegerArrayList( String key, ArrayList<Integer> value) .withSparseParcelableArray( String key, SparseArray<? extends Parcelable> value) .withCharSequenceArrayList( String key, ArrayList<CharSequence> value) .withShortArray( String key, short[] value) .withCharArray( String key, char[] value) .withFloatArray( String key, float[] value) .withCharSequenceArray( String key, CharSequence[] value) //Bundle 类型 .with( Bundle bundle ) //Activity 跳转动画 .withTransition(int enterAnim, int exitAnim) //其余类型 .withParcelable( String key, Parcelable value) .withParcelableArray( String key, Parcelable[] value) .withSerializable( String key, Serializable value) .withByteArray( String key, byte[] value) .withTransition(int enterAnim, int exitAnim) 
 

运行程序,结果以下图所示:

 
 

路由监听
在路由跳转的过程当中,咱们能够监听路由的过程,只须要如下使用:

navigation(Context context, NavigationCallback callback)

NavigationCallback 的源码以下:

public interface NavigationCallback { /** * Callback when find the destination. * 找到了 * @param postcard meta */ void onFound(Postcard postcard); /** * Callback after lose your way. * 找不到了 * @param postcard meta */ void onLost(Postcard postcard); /** * Callback after navigation. * 跳转完了 * @param postcard meta */ void onArrival(Postcard postcard); /** * Callback on interrupt. * 被拦截了 * @param postcard meta */ void onInterrupt(Postcard postcard); } 

添加用于测试跳转的页面

 
 

在跳转的页面中添加监听代码

 

运行结果以下:

 
 
 

拦截器使用
添加须要跳转的页面

 

添加拦截器

 

在主页面进行跳转拦截测试

 

路由分组
在前面咱们讲到在对 Activity1 作注解的时候,用到了

@Route(path = "/com/Activity1") public class Activity1 extends AppCompatActivity {} 

  在 path 这个字符串里面,”com” 就表明组的标识;“Activity1” 表明是 Activity1 类的具体表示。组的标识和类的标识均可以本身定义的,须要记住的是组标识和类标识之间用斜杠来区分 ”\” .

什么是组?
  这里就须要提下,ARouter框架是分组管理,按需加载。提起来很高深的样子呢!其实解释起来就是,在编译期框架扫描了全部的注册页面/服务/字段/拦截器等,那么很明显运行期不可能一股脑所有加载进来,这样就太不和谐了。因此就分组来管理,ARouter在初始化的时候只会一次性地加载全部的root结点,而不会加载任何一个Group结点,这样就会极大地下降初始化时加载结点的数量。好比某些Activity分红一组,组名就叫test,而后在第一次须要加载组内的某个页面时再将test这个组加载进来。

测试一下:

ARouter.getInstance()
       .build("/wxc/Activity1") .navigation(this, new NavCallback() { @Override public void onArrival(Postcard postcard) { String group = postcard.getGroup(); Log.e("zhao", "分组是: " + group); } }); 

结果是

07-27 17:32:17.880 19449-19449/com.router E/zhao: 分组是: wxc

ARouter 默认状况下的分组就是第一个 / / 之间的内容。

自定义分组
  建立 CustomGroupActivity 而且添加 注解,而且指定路由分组。自定义分组的就是在原来的注解上添加 group 字段, 以下所示。

@Route(path = "/com/CustomGroupActivity" , group = "customGroup") public class CustomGroupActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_custom_group); } } 

自定义分组,发起路由:第二个参数就是路由的分组

build(String path, String group) 

具体实现以下所示:

ARouter.getInstance().build("/com/CustomGroupActivity", "customGroup").navigation(); 

URL 跳转
web url 跳转流程图

 

建立URL 中间跳转页
建立 URLReceiveActivity

/** * URL 中转Activity */ public class URLReceiveActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView( R.layout.activity_url_receive ); //对URI 数据分发 Uri uri = getIntent().getData(); ARouter.getInstance().build(uri).navigation(this, new NavCallback() { @Override public void onArrival(Postcard postcard) { finish(); } }); } } 

URLReceiveActivity 添加注册

<activity android:name=".URLReceiveActivity"> <!-- Schame --> <intent-filter> <data android:host="zhaoyanjun" android:scheme="arouter" /> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> </intent-filter> </activity> 

这里面的 host 、scheme 字段很重要。点击 url 会根据这两个字段会调起本地的 Activity 。

下面是一段 HTML 片断

<h2>1:URL普通跳转</h2> <p><a href="arouter://zhaoyanjun/com/URLActivity1">arouter://zhaoyanjun/com/URLActivity1 </a> </p> <h2>2:URL普通跳转携带参数</h2> <p> <a href="arouter://zhaoyanjun/com/URLActivity2?name=alex&age=18&boy=true&high=180&obj=%7b%22name%22%3a%22jack%22%2c%22id%22%3a666%7d">arouter://zhaoyanjun/test/URLActivity2?name=alex&age=18&boy=true&high=180&obj={"name":"jack","id":"666"} </a> </p> 

注意 a 标签里面的 arouter://zhaoyanjun 分别表明着 scheme 、host ;/com/URLActivity1 就是目标 Activity 的注解。

若是须要接收 URL 中的参数,须要在 Activity 调用自动注入初始化方法;

ARouter.getInstance().inject(this); 

须要注意的是,若是不使用自动注入,那么能够不写 ARouter.getInstance().inject(this),可是须要取值的字段仍然须要标上 @Autowired 注解,由于 只有标上注解以后,ARouter才能知道以哪种数据类型提取URL中的参数并放入Intent中,这样您才能在intent中获取到对应的参数

具体的代码以下:

@Route(path = "/com/URLActivity2") public class URLActivity2 extends AppCompatActivity{ private TextView textView; @Autowired String name; @Autowired int age; @Autowired boolean boy; @Autowired int high; @Autowired String obj ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ARouter.getInstance().inject(this); setContentView(R.layout.activity_url2); textView = (TextView) findViewById(R.id.tv); //解析参数 Bundle bundle = getIntent().getExtras(); String name1 = bundle.getString("name"); textView.setText("参数是: " + "name: " + name + " age: " + age + " boy: " + boy + " name1: " + name1 + " obj: " + obj.toString() ); } } 

效果图以下:

 

暴露服务
  这里说到的服务不是Android四大组件中的Service,这里的服务是接口开发的概念,就是将一部分功能和组件封装起来成为接口,以接口的形式对外提供能力,因此在这部分就能够将每一个功能做为一个服务,而服务的实现就是具体的业务功能。

咱们先自定义一个接口 IService 而且继承 IProvider 。IService 接口里面有一个 sayHello() 方法,具体代码以下。

public interface IService extends IProvider { void sayHello(Context context ); } 

先定义一个 IService 的实现类 MyService 而且添加注解,代码以下

@Route(path = "/service/hello", name = "测试服务") public class MyService implements IService { @Override public void sayHello( Context context ) { Toast.makeText( context , "hello", Toast.LENGTH_SHORT).show(); } @Override public void init(Context context) { } } 

发现服务,首先定义服务对象,而且添加注解,咱们不须要知道接口的具体实现类。

@Autowired(name = "/service/hello") IService service; 

而后添加注解初始化,自动赋值。

ARouter.getInstance().inject(this); 

最后咱们调用 service 里面的 sayHello() 方法。

service.sayHello(this); 

发现服务这个功能的特色在于,咱们只须要知道接口,不须要关心接口的实现类,很好了实现了解耦。

路由关闭

ARouter.getInstance().destroy(); 

舒适提示:该功能慎用,搞很差整个app页面跳转就gg了。

代码混淆
  若是咱们使用了Proguard进行代码混淆,能够添加如下代码

-keep public class com.alibaba.android.arouter.routes.**{*;} -keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;} 

2.常见应用场景

  1. 从外部URL映射到内部页面,以及参数传递与解析
    说明:该场景使用到了该文章的URL跳转和暴露服务功能,这样使得页面跳转功能很好的解耦,特别对于团队开发有很好管理做用。
  2. 跨模块页面跳转,模块间解耦
  3. 处理登录、埋点等逻辑
    说明:该场景使用到了路由监听和拦截跳转等功能,在原始处理登录、埋点等功能中,咱们会先初始化Activity,再进行逻辑判断,这样会影响性能,若是咱们使用了监听和拦截,那么在初始化新的Activity以前,咱们能够先进行逻辑判断。

3、源码下载

连接:https://pan.baidu.com/s/1Y7Br3iKlDb-55VG1kAU70A
提取码:m0at

4、参考文章

    1. https://www.cnblogs.com/zhujiabin/p/7193400.html
    2. https://blog.csdn.net/x605940745/article/details/80583912
    3. https://blog.csdn.net/zhaoyanjun6/article/details/76165252

原文出处:https://www.cnblogs.com/WUXIAOCHANG/p/10550408.html

相关文章
相关标签/搜索