美文网首页
ARouter疑问

ARouter疑问

作者: orgcheng | 来源:发表于2020-04-20 17:55 被阅读0次

一、通过路由创建Fragment实例不会触发拦截器

使用示例:

// app模块创建fragment实例
Fragment fragment = (Fragment) ARouter.getInstance().build("/router/frag").navigation();
if (null != fragment) {
    getSupportFragmentManager().beginTransaction().add(R.id.frag, fragment)
        .commitAllowingStateLoss();
}

// 其他模块定义fragment
@Route(path = "/router/frag")
public class RouterFragment extends Fragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_router, container, false);
    }
}

在这个过程中,Arouter拦截器不会触发

首先ARouter.getInstance().build("/router/frag");会返回Postcard对象

之后调用Postcard.navigation()方法,最终调用了:

_ARouter.navigation(final Context context, final Postcard postcard, 
                    final int requestCode, final NavigationCallback callback)

这个方法内部调用下面的方法,传递postcard对象,并调用postcard.greenChannel();

LogisticsCenter.completion(postcard);

通过分析LogisticsCenter.completion(postcard); 可以了解到,当PostCard.getType()RouteType.PROVIDER 或者 RouteType.FRAGMENT时:

  • 都会不会触发拦截器,因为调用了postcard.greenChannel();
  • PostCard.navigation()方法后,直接返回对应的对象实例

二、拦截器的初始化和责任链模式调用

ARouter.init()内部会调用_ARouter.afterInit()方法,获取InterceptorServiceImpl对象,对象在创建时调用了init方法进行初始化

package com.alibaba.android.arouter.core;

@Route(path = "/arouter/service/interceptor")
public class InterceptorServiceImpl implements InterceptorService {

    @Override
    public void init(final Context context) {
        // 初始化所有的拦截器对象,并调用其init方法
    }
    
    @Override
    public void doInterceptions(final Postcard postcard, 
    final InterceptorCallback callback) {
        ...
        // 进行Activity跳转时,会触发该方法
        // 采用责任链模式
    }
    
}

举个喝水给学生喝水的例子来说明下责任链模式:

  • InterceptorServiceImpl类是老师
  • PostCard是一瓶水
  • 拦截器是要喝水的学生
  • 拦截器列表是要喝水的学生列表

老师把水给学生0,学生0喝了水,把水还给老师

老师把水给学生1,学生1喝了水,把水还给老师

老师把水给学生2,学生2喝了水,这个时候学生2比较口渴,把水喝完了,把空瓶子还给老师

老师说没水了,活动结束

学生3、学生4就没水喝了,水被学生2“拦截了”

看下ARouter初始化的流程

// ARouter.java文件
/**
 * Init, it must be call before used router.
 */
public static void init(Application application) {
    if (!hasInit) {
        hasInit = _ARouter.init(application);
        if (hasInit) {
            _ARouter.afterInit();   //这里触发拦截器的加载和初始化
        }
    }
}

// _ARouter.java文件
    static void afterInit() {
        // Trigger interceptor init, use byName.
        interceptorService = (InterceptorService) ARouter.getInstance()
            //这里通过注解找到实现类InterceptorServiceImpl
            .build("/arouter/service/interceptor")  
            .navigation(); // 返回实例对象时,调用对象的init方法
    }


三、ARouter框架默认提供的类信息

package com.alibaba.android.arouter.routes;
public class ARouter$$Group$$arouter implements IRouteGroup {
    public void loadInto(Map<String, RouteMeta> atlas) {
        atlas.put("/arouter/service/autowired", RouteMeta.build(RouteType.PROVIDER, AutowiredServiceImpl.class, "/arouter/service/autowired", "arouter", (Map)null, -1, -2147483648));
        atlas.put("/arouter/service/interceptor", RouteMeta.build(RouteType.PROVIDER, InterceptorServiceImpl.class, "/arouter/service/interceptor", "arouter", (Map)null, -1, -2147483648));
    }
}

public class ARouter$$Providers$$arouterapi implements IProviderGroup {
    public void loadInto(Map<String, RouteMeta> providers) {
        providers.put("com.alibaba.android.arouter.facade.service.AutowiredService", RouteMeta.build(RouteType.PROVIDER, AutowiredServiceImpl.class, "/arouter/service/autowired", "arouter", (Map)null, -1, -2147483648));
        providers.put("com.alibaba.android.arouter.facade.service.InterceptorService", RouteMeta.build(RouteType.PROVIDER, InterceptorServiceImpl.class, "/arouter/service/interceptor", "arouter", (Map)null, -1, -2147483648));
    }
}

public class ARouter$$Root$$arouterapi implements IRouteRoot {
    public void loadInto(Map<String, Class<? extends IRouteGroup>> routes) {
        routes.put("arouter", arouter.class);
    }
}

相关文章

网友评论

      本文标题:ARouter疑问

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