美文网首页
Android 路由框架

Android 路由框架

作者: R7_Perfect | 来源:发表于2020-06-12 11:58 被阅读0次

    为什么要用路由框架,路由框架哪些好处等等,在此就不做解释
    最常用的框架是ARouter
    那是不是可以自己写一个路由框架呢,不参考ARouter的方式

    首先说说 模块化
    每个模块各自维护自己的跳转或其他规则(如打开相机)
    先定义一个模块处理器,用来处理上诉规则
    这个模块处理器需要如下功能:

    • 运行路由url入口
    • 对象传递
    • 预处理url
    • 解析url
    • 处理解析后结果
    企业微信截图_15919320138763.png

    以上步骤,开放给调用者只需要解析url这一步

    public abstract class AbsRouterProcessor implements IProcessInterface<RouterAction> {
       //这是外部调用的入口
     @Override
        public boolean execute(Context context, String url, IRouterHandler handler, IResultCallback callback, IRouterConfig routerConfig) throws RouterException{
            mContext = context;
            RouterAction action = processUrl(url, routerConfig);
            return processResult(action, handler, callback);
        }
    }
    

    处理url

    processUrl 中主要做了预处理和解析url,来得到最终的RouterAction,交给结果处理器去处理:

        private RouterAction processUrl(String url, IRouterConfig routerConfig) throws RouterException{
            RouterAction action = preprocess(url, routerConfig);
            process(action);
            return action;
        }
    
        protected RouterAction preprocess(String url, IRouterConfig routerConfig) throws RouterException{
            CommPreProcessor preProcessor = new CommPreProcessor(mContext);
            RouterAction action = preProcessor.prePorcess(url, routerConfig);
            return action;
        }
    
        protected void process(RouterAction action) throws RouterException{
            mapping(mContext, action);
            action.setBundle(bundle);
        }
    
    • RouterAction:先来看下RouterAction,主要是给后续处理器封装的对象,看看其定义的结构:
        private int requestCode;// activity requestCode
        private String packageName;// 传递参数(多进程使用)
        private String originalUrl;//原始url
        private int targetType;//目标类型,有activity,fragment或自定义类型
        private Bundle bundle;//供大对象使用
        private T target;//目标对象,activity为Intent,fragment为Fragment
        private String path;//url path
        private Parameters parameters;//url 参数
        private int intentFlag;//如果是intent,代表intentFlag
    
    • IRouterConfig 定义了此次路由的SCHEME和HOST,由调用者初始化时传递进来
    public interface IRouterConfig extends RouterConfig {
        String getScheme();
        String getHost();
        String getPackageName();
    }
    
    • CommPreProcessor是自带的预处理器,也可以自定义预处理器
    public class CommPreProcessor implements IPreProcessInterface<RouterAction> {
    ...
     @Override
        public RouterAction prePorcess(String url, IRouterConfig routerConfig) throws RouterException {
           //将url转化为RouterAction 
        }
    }
    
    • mapping方法是调用这需要override的方法,主要是实现匹配规则

    比如我们定义了一个Home的Module,则需要自定一个Processor:

    public class HomeRouteProcessor extends AbsRouterProcessor {
        @Override
        protected void mapping(Context context, RouterAction action) {
           if("/open/native/home".equals(path)) {
                action.setTargetType(RouterAction.TYPE_ACTIVITY);
                Intent intent = new Intent(mContext, HomeActivity.class);
                action.setTarget(intent);
            } else if(...) {
                 ...
            }
        }
    }
    

    处理结果

    得到RouterAction后,就可以处理结果了,再此,调用这可以自定义处理器,如果不传入自定义处理器,工程则会处理Activity,Fragment和Service三种类型
    传入自定义处理器:
    在入口函数execute中传入
    1.自定义处理器
    2.结果接收器

    @Override
        public boolean execute(Context context, String url, IRouterHandler handler, IResultCallback callback, IRouterConfig routerConfig) throws RouterException{
    }
    

    处理器只需实现IRouterHandler接口
    拿ActivityHandler举例:

    public class ActivityHandler implements IRouterHandler {
    
        public boolean handle(final Context context, RouterAction action, final IResultCallback callback) throws RouterException {
            ...
           Parameters parameters = action.getParameters();
            if(parameters != null) {
               //parameters 处理
            }
            Bundle bundle = action.getBundle();
            //bundle 处理
    
            //intent flag
           int flag = action.getIntentFlag();
            if(flag > 0) {
                intent.addFlags(flag);
            }
            final int requestCode = action.getRequestCode();
             new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                     if (context instanceof Activity) {
                         if(requestCode > 0) {
                             ((Activity) context).startActivityForResult(intent, requestCode);
                          } else {
                             context.startActivity(intent);
                         }
                    } else {
                        context.startActivity(intent);
                    }
                    if (null != callback) { // Navigation over.
                        callback.onResult(true);
                    }
                }
            });
        }
    }
    

    注意:此处结果接收器callback返回的是true,如果是fragment,此处返回的就是fragment对象,如果是自定义IRouterHandler ,callback返回的则是自定义对象

    以上则是整个处理流程
    但还有一步就是注册

    注册

    首先定义一个对外类UrlRouteManager,功能相当于接口

    • 注册
    • 注销
    • 查找
    public class UrlRouteManager {
        private UrlRouterCore core;
        public void registerProtocol(String path, int group, IProcessInterface processor) throws RouterException{
            if(core == null) {
                throw new RouterException("please call init method first");
            }
            core.registerProtocol(path, group, processor);
        }
    
        public void unRegisterProtocol(int group) throws RouterException{
            if(core == null) {
                throw new RouterException("please call init method first");
            }
            core.unRegisterProtocol(group);
        }
      
       public IProcessInterface seek(String url, int group) throws RouterException{
            if(core == null) {
                throw new RouterException("please call init method first");
            }
            return core.getTargetIProcessor(url, group);
        }
    }
    

    真正实现的是UrlRouterCore这个类

    public void registerProtocol(String regx, int group, IProcessInterface processor) throws RouterException{
            ...
            Map<String, IProcessInterface> map = processorList.get(group);
            if(map == null)
                map = new HashMap<String, IProcessInterface>();
            map.put(regx, processor);
            processorList.put(group, map);
        }
    

    以group为分组,将processor放到一个SparseArray中
    看下seek的实现

    public IProcessInterface getTargetIProcessor(String url, int group) {
            Map<String, IProcessInterface> map = processorList.get(group);
            if(map == null) {
                return null;
            }
            IProcessInterface processInterface = null;
            Iterator iter = map.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<String, IProcessInterface> entry = (Map.Entry<String, IProcessInterface>) iter.next();
                String key = entry.getKey();
                IProcessInterface val = entry.getValue();
                String[] strArray = MathUtils.getMatchStr(url, key);
                if(strArray != null && strArray.length > 0) {
                    processInterface = val;
                    break;
                }
            }
            return processInterface;
        }
    

    根据分组和url找到对应的IProcessInterface ,在execute函数执行时,会自动运行找到对应的IProcessInterface

    看看调用者如何注册:
    步骤一:定义module的注册器,并将processor绑定

    public class HomeModuleRegister extends ProcessorRegister {
        private String regex1 = RobinRouterConfig.SCHEME + "://" + RobinRouterConfig.HOST + "/open/native/home/tab1";
        private String regex2 = RobinRouterConfig.SCHEME + "://" + RobinRouterConfig.HOST + "/open/native/home";
     private int group = RobinRouterConfig.GROUP_HOME;
    @Override
        public void register() {
            HomeRouteProcessor processor = new HomeRouteProcessor();
            UrlRouteManager.getInstance().init(new RobinRouterConfig());
            try {
                UrlRouteManager.getInstance().registerProtocol(regex1, group, processor);
                UrlRouteManager.getInstance().registerProtocol(regex2, group, processor);
            } catch (RouterException e) {
                e.printStackTrace();
            }
        }
    }
    

    步骤二:在application中初始化与注册

    public class DemoApplication extends Application {
        private ProcessorRegister processorRegister;
        @Override
        public void onCreate() {
            super.onCreate();
    
            //注册
            processorRegister = new HomeModuleRegister();
            processorRegister.register();
        }
    }
    

    末尾

    大致实现思路就如上述所说
    使用方式在github上有详细说明
    源码地址 https://github.com/robinfjb/Android-Router

    相关文章

      网友评论

          本文标题:Android 路由框架

          本文链接:https://www.haomeiwen.com/subject/uzwbtktx.html