Arouter 框架是主要由三个模块组成,annotation,compiler,core.
annotation :自定义注解,用来声明需要路由的页面(Java Library)
compiler :注解解析,在编译时根据自定义注解生成注册路由表的java类(Java Library)。
core : 实现路由跳转功能,供Android调用(Android Library)

先上工程结构图

一、annotation模块

新建一个文件,编写一个注解,声明路由路径

RouteMeta保存路由信息,通过解析注解获取。

二、compiler模块

  1. 首先导入依赖的第三方库,compiler模块使用javax的Processor类来解析注解,auto-service自动编译Processor类,使用javapoet库生成java类。

  2. 新建RouterProcessor继承AbstractProcessor类,添加如下注解

     

    初始化RouterProcessor,在process方法中遍历Route注解的节点,如果不为null,进行解析

    获取Activity类的节点信息,然后循环,判断是Activity类型的节点,新建RouteMeta对象保存节点信息。然后调用categories()验证节点的路由地址是否符合规则,再根据分组名保存节点到groupMap中

遍历groupMap中的节点信息,使用javapoet工具生成一个继承IRouteGroup接口的java类,用来保存每个分组的路由信息。叫分组信息类。

 

然后遍历所有的分组信息类,生成继承IRouteRoot接口的表信息类,保存分组名对应的分组信息类。

 

三、core模块

  1. 定义一个路由表保存所有的路由信息

     

  2. 然后,遍历所有的dex文件,查找所有的使用javapoet生成的分组信息类和表信息类。查找是一个耗时操作,使用ThreadPoolExecutor维护一个线程池,来查找所有包名为com.hc.androiddemo.routes 类,并使用使用同步计数器来判断查找是否完成。然后将分组信息类加入Warehouse的groupsIndex中

     

     

四、跳卡PostCard

Postcard继承RouteMeta类,保存路由地址、分组名以及要传递的数据。使用Postcard的with方法添加传递的数据,调用Postcard的navigation()进行页面跳转

public class Postcard extends RouteMeta {    private Bundle mBundle;    //新版风格    private Bundle optionsCompat;    private int flags = -1;    public Postcard(String path, String group) {        this(path, group, null);    }    public Postcard(String path, String group, Bundle bundle) {        setPath(path);        setGroup(group);        this.mBundle = (null == bundle ? new Bundle() : bundle);    }    public Bundle getExtras() {return mBundle;}    public Bundle getOptionsBundle() {        return optionsCompat;    }    /**     * Intent.FLAG_ACTIVITY**     * @param flag     * @return     */    public Postcard withFlags(int flag) {        this.flags = flag;        return this;    }    public Postcard withString(String key,String value){        mBundle.putString(key,value);        return this;    }    public Postcard withInt(String key,int value){        mBundle.putInt(key,value);        return this;    }    public Postcard withBoolean(String key,boolean value){        mBundle.putBoolean(key,value);        return this;    }    public int getFlags() {        return flags;    }    public Object navigation() {        return ToolRouter.getInstance().navigation(null, this, -1, null);    }    public Object navigation(Context context) {        return ToolRouter.getInstance().navigation(context, this, -1, null);    }    public Object navigation(Context context, NavigationCallback callback) {        return ToolRouter.getInstance().navigation(context, this, -1, callback);    }    public Object navigation(Context context, int requestCode) {        return ToolRouter.getInstance().navigation(context, this, requestCode, null);    }    public Object navigation(Context context, int requestCode, NavigationCallback callback) {        return ToolRouter.getInstance().navigation(context, this, requestCode, callback);    }}

五、跳转页面

调用Postcard的navigation()进行跳转。

 protected Object navigation(Context context, final Postcard postcard, final int requestCode,                                final NavigationCallback callback) {        try {            //准备卡片,路由信息            prepareCard(postcard);        } catch (NoRouteFoundException e) {            e.printStackTrace();            if (null != callback) {                callback.onLost(postcard);            }            return null;        }        if (null != callback) {            callback.onFound(postcard);        }        switch (postcard.getType()) {            case ACTIVITY:                final Context currentContext = null == context ? mContext : context;                final Intent intent = new Intent(currentContext, postcard.getDestination());                intent.putExtras(postcard.getExtras());                int flags = postcard.getFlags();                if (-1 != flags) {                    intent.setFlags(flags);                } else if (!(currentContext instanceof Activity)) {                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                }                mHandler.post(new Runnable() {                    @Override                    public void run() {                        //带返回码                        if(requestCode > 0 ){                            ActivityCompat.startActivityForResult((Activity) currentContext,intent,requestCode,postcard.getExtras());                        }else {                            ActivityCompat.startActivity(currentContext,intent,postcard.getExtras());                        }                        if(null != callback){                            callback.onArrival(postcard);                        }                    }                });                break;        }        return null;    }

先准备路由的卡片信息,如果没有准备路由信息,根据分组名从Warehouse的groupsIndex中找到分组信息类,加载对应路由表的信息。这里实现了按需加载。获取到路由信息后,设置postcard的信息。再调用startActivity来跳转

private void prepareCard(Postcard postcard) {        RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());        if (null == routeMeta) {//还没有准备信息            //创建并调用 loadinto 函数  然后记录在仓库            Class<? extends IRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard                    .getGroup());            if (null == groupMeta) {                throw new NoRouteFoundException("没找到对应路由: " + postcard.getGroup() + " " +                        postcard.getPath());            }            IRouteGroup iGroupInstance = null;            try {                iGroupInstance = groupMeta.getConstructor().newInstance();            } catch (Exception e) {                e.printStackTrace();            }            iGroupInstance.loadInto(Warehouse.routes);            //已经准备过了就可以移除了            Warehouse.groupsIndex.remove(postcard.getGroup());            //再次进入else            prepareCard(postcard);        } else {            //获取要跳转的activity            postcard.setDestination(routeMeta.getDestination());            postcard.setType(routeMeta.getType());//            switch (routeMeta.getType()){////            }        }    }

六、使用

1.在Application中进行初始化

public class App extends Application {    @Override    public void onCreate() {        super.onCreate();        initToolRouter();    }    private void initToolRouter() {        ToolRouter.init(this);    }}

2.在FirstActivity 和MainActivity中添加注解,在MainActivity中点击按钮进行跳转

@Route(path = "/demo1/fisrtActivity")public class FirstActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_first);    }}

 

@Route(path = "/demo2/MainActivity")public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private Button jump_btn;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        jump_btn = findViewById(R.id.jump_btn);        jump_btn.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.jump_btn:                ToolRouter.getInstance().build("/demo1/fisrtActivity")                        .navigation();                break;        }    }}

3.编译期生成的java文件目录如下

在这里我也分享自己收录整理的Android学习PDF,里面对仿写Arouter框架实现Activity的跳转讲解,希望可以帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,可以分享给身边好友一起学习

有需要的朋友可以点赞+评论+转发,关注我,然后私信我【666】获取

也可以加入粉丝群获取:

更多相关文章

  1. 获取andrid apn信息
  2. Android(安卓)Studio gradle 使用最新版本的 xstream:1.4.8 出错
  3. Android(安卓)如何获取 umeng 的 渠道信息
  4. Android中GUI系统的Event路由机制
  5. 应用程序中捕获home按键事件
  6. MQTT——activemq5.8 推送消息实现
  7. Android6.0(包括)以后获取Wifi 扫描信息列表即getScanResults()
  8. Android服务器端和客户端设计APK升级
  9. Android(安卓)手机 Google Play 商店“从服务器检索信息时出错 [

随机推荐

  1. android 写入data/data/包名/file/中
  2. android boot
  3. Android 使用Handler模仿流行的AsyncHttp
  4. android googlemap的location报空指针解
  5. android技术博客汇总
  6. 如何使用 Android Studio 的 git hub 功
  7. Android(安卓)用GridView做横向滚动
  8. Android debug :arm-linux-androideabi-a
  9. How to create a custom notification on
  10. android倒计时的简单实现