为什么要用路由框架,路由框架哪些好处等等,在此就不做解释
最常用的框架是ARouter
那是不是可以自己写一个路由框架呢,不参考ARouter的方式
首先说说 模块化
每个模块各自维护自己的跳转或其他规则(如打开相机)
先定义一个模块处理器,用来处理上诉规则
这个模块处理器需要如下功能:
- 运行路由url入口
- 对象传递
- 预处理url
- 解析url
- 处理解析后结果
以上步骤,开放给调用者只需要解析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
网友评论