美文网首页
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