美文网首页
ARouter简单分析

ARouter简单分析

作者: feifei_fly | 来源:发表于2020-03-05 10:12 被阅读0次

    一、ARouter基本使用方法

    ARouter初始化

      ARouter.openDebug();
                    ARouter.init(getApplication());
    

    1、Actvity跳转

    定义换一个Actvity的@Route

    @Route(path = "/test/activity1", name = "测试用 Activity")
    public class Test1Activity extends AppCompatActivity {
    
        @Autowired(desc = "姓名")
        String name = "jack";
        
          @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_test1);          ARouter.getInstance().inject(this);
              
          }
    }
    

    ARouter跳转:

     ARouter.getInstance()
                            .build("/test/activity1")
                            .withString("name", "老王")
                            .navigation();
    

    2、Provider的使用

    HellopSevice.java

    public interface HelloService extends IProvider {
        void sayHello(String name);
    }
    
    

    HelloServiceImpl.java
    用@Route定义一个路由,其基类是IProvider故其类型是一个Provider

    @Route(path = "/yourservicegroupname/hello")
    public class HelloServiceImpl implements HelloService {
        Context mContext;
    
        @Override
        public void sayHello(String name) {
            Toast.makeText(mContext, "Hello " + name, Toast.LENGTH_SHORT).show();
        }
    
        /**
         * Do your init work in this method, it well be call when processor has been load.
         *
         * @param context ctx
         */
        @Override
        public void init(Context context) {
            mContext = context;
            Log.e("testService", HelloService.class.getName() + " has init.");
        }
    }
    
    

    调用HelloService

     ((HelloService) ARouter.getInstance().build("/yourservicegroupname/hello").navigation()).sayHello("mike");
    

    3、interceptor的使用

    使用@Interceptor注解,定义一个Interceptor拦截器,自动会加入interceptors拦截器列表

    @Interceptor(priority = 7)
    public class Test1Interceptor implements IInterceptor {
        Context mContext;
    
        /**
         * The operation of this interceptor.
         *
         * @param postcard meta
         * @param callback cb
         */
        @Override
        public void process(final Postcard postcard, final InterceptorCallback callback) {
            if ("/test/activity4".equals(postcard.getPath())) {
    
                // 这里的弹窗仅做举例,代码写法不具有可参考价值
                final AlertDialog.Builder ab = new AlertDialog.Builder(MainActivity.getThis());
                ab.setCancelable(false);
                ab.setTitle("温馨提醒");
                ab.setMessage("想要跳转到Test4Activity么?(触发了\"/inter/test1\"拦截器,拦截了本次跳转)");
                ab.setNegativeButton("继续", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        callback.onContinue(postcard);
                    }
                });
                ab.setNeutralButton("算了", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        callback.onInterrupt(null);
                    }
                });
                ab.setPositiveButton("加点料", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        postcard.withString("extra", "我是在拦截器中附加的参数");
                        callback.onContinue(postcard);
                    }
                });
    
                MainLooper.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        ab.create().show();
                    }
                });
            } else {
                callback.onContinue(postcard);
            }
        }
    
        /**
         * Do your init work in this method, it well be call when processor has been load.
         *
         * @param context ctx
         */
        @Override
        public void init(Context context) {
            mContext = context;
            Log.e("testService", Test1Interceptor.class.getName() + " has init.");
        }
    }
    

    拦截器的监听

     ARouter.getInstance()
                            .build("/test/activity4")
                            .navigation(this, new NavCallback() {
                                @Override
                                public void onArrival(Postcard postcard) {
    
                                }
    
                                @Override
                                public void onInterrupt(Postcard postcard) {
                                    Log.d("ARouter", "被拦截了");
                                }
                            });
    

    二、ARouter的核心类

    1、RouteMeta 存储一个路由的元信息

    public class RouteMeta {
        private RouteType type;         // Type of route
        private Element rawType;        // Raw type of route
        private Class<?> destination;   // Destination
        private String path;            // Path of route
        private String group;           // Group of route
        private int priority = -1;      // The smaller the number, the higher the priority
        private int extra;              // Extra data
        private Map<String, Integer> paramsType;  // Param type
        private String name;
    
        private Map<String, Autowired> injectConfig;  // Cache inject config.
    
        public RouteMeta() {
        }
    }
    

    其中最主要的信息:

    • path 路由路径
    • group 路由分组
    • destination 目的地,即加载的类对象,可以是Activity、Provider、Fragment的子类
    • type 是哪种类型的路由:如Activity、Provider、Fragment

    2、PostCard 明信片

    
    public final class Postcard extends RouteMeta {
        // Base
        private Uri uri;
        private Object tag;             // A tag prepare for some thing wrong.
        private Bundle mBundle;         // Data to transform
        private int flags = -1;         // Flags of route
        private int timeout = 300;      // Navigation timeout, TimeUnit.Second
        private IProvider provider;     // It will be set value, if this postcard was provider.
        private boolean greenChannel;
        private SerializationService serializationService;
    
        // Animation
        private Bundle optionsCompat;    // The transition animation of activity
        private int enterAnim = -1;
        private int exitAnim = -1;
        
          public Object navigation(Context context, NavigationCallback callback) {
            return ARouter.getInstance().navigation(context, this, -1, callback);
        }
    }
    

    postCard 继承自RouteMeta
    又增加了一些额外的属性

    • Bundle mBundle :Activity跳转时 传递的参数
    • flags :Activity跳转时的flags标记
    • timeout :路由超时时间
    • enterAnim 和exitAnim 进入进出的动画
    • IProvider provider 缓存的provider对象

    它的一个核心方法navigation 最终代理到了
    ARouter.getInstance().navigation(context, this, -1, callback);

    3、Warehouse 仓库类,它里面保存所有的路由信息集合

    class Warehouse {
        // Cache route and metas
        static Map<String, Class<? extends IRouteGroup>> groupsIndex = new HashMap<>();
        static Map<String, RouteMeta> routes = new HashMap<>();
    
        // Cache provider
        static Map<Class, IProvider> providers = new HashMap<>();
        static Map<String, RouteMeta> providersIndex = new HashMap<>();
    
        // Cache interceptor
        static Map<Integer, Class<? extends IInterceptor>> interceptorsIndex = new UniqueKeyTreeMap<>("More than one interceptors use same priority [%s]");
        static List<IInterceptor> interceptors = new ArrayList<>();
    
        static void clear() {
            routes.clear();
            groupsIndex.clear();
            providers.clear();
            providersIndex.clear();
            interceptors.clear();
            interceptorsIndex.clear();
        }
    }
    
    
    • groupsIndex 保存所有的分组
     static Map<String, Class<? extends IRouteGroup>> groupsIndex = new HashMap<>();
    
    • routes缓存所有的路由信息。但是分级缓存的,用到一个IRouteGroup分组时,就将该分组中的路由信息加载到routes中。
     static Map<String, RouteMeta> routes = new HashMap<>();
    
    
    • providersIndex 缓存的是provider的路由表(与routes会有部分重合),推测可能考虑到provider数量较少,为了加快查询速度,就直接将所有的provider路由一次性加载进了providersIndex
      static Map<String, RouteMeta> providersIndex = new HashMap<>();
    
    
    • providers 缓存的是某个路由对应的provider的实例。以单例实现。
       static Map<Class, IProvider> providers = new HashMap<>();
    
    • interceptorsIndex 和interceptors 缓存的是所有的来拦截器
    static Map<Integer, Class<? extends IInterceptor>> interceptorsIndex = new UniqueKeyTreeMap<>("More than one interceptors use same priority [%s]");
        static List<IInterceptor> interceptors = new ArrayList<>();
    

    WareHouse的加载过程如下:

           Set<String> routerMap;
    
                    // It will rebuild router map every times when debuggable.
                    if (ARouter.debuggable() || PackageUtils.isNewVersion(context)) {
                        logger.info(TAG, "Run with debug mode or new install, rebuild router map.");
                        // These class was generated by arouter-compiler.
                        routerMap = ClassUtils.getFileNameByPackageName(mContext, ROUTE_ROOT_PAKCAGE);
                        if (!routerMap.isEmpty()) {
                            context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).edit().putStringSet(AROUTER_SP_KEY_MAP, routerMap).apply();
                        }
    
                        PackageUtils.updateVersion(context);    // Save new version name when router map update finishes.
                    } else {
                        logger.info(TAG, "Load router map from cache.");
                        routerMap = new HashSet<>(context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).getStringSet(AROUTER_SP_KEY_MAP, new HashSet<String>()));
                    }
    
                    logger.info(TAG, "Find router map finished, map size = " + routerMap.size() + ", cost " + (System.currentTimeMillis() - startInit) + " ms.");
                    startInit = System.currentTimeMillis();
    
                    for (String className : routerMap) {
                        if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_ROOT)) {
                            // 对RooT的处理
                            // This one of root elements, load root.
                            ((IRouteRoot) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.groupsIndex);
                        } else if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_INTERCEPTORS)) {
                            // Load interceptorMeta
                            //interceptor 的处理
                            ((IInterceptorGroup) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.interceptorsIndex);
                        } else if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_PROVIDERS)) {
                            // Load providerIndex
                            //provider的处理
                            ((IProviderGroup) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.providersIndex);
                        }
                    }
                }
    
    public final class Consts {
        public static final String SDK_NAME = "ARouter";
        public static final String TAG = SDK_NAME + "::";
        public static final String SEPARATOR = "$$";
        public static final String SUFFIX_ROOT = "Root";
        public static final String SUFFIX_INTERCEPTORS = "Interceptors";
        public static final String SUFFIX_PROVIDERS = "Providers";
        public static final String SUFFIX_AUTOWIRED = SEPARATOR + SDK_NAME + SEPARATOR + "Autowired";
        public static final String DOT = ".";
        public static final String ROUTE_ROOT_PAKCAGE = "com.alibaba.android.arouter.routes";
    
        public static final String AROUTER_SP_CACHE_KEY = "SP_AROUTER_CACHE";
        public static final String AROUTER_SP_KEY_MAP = "ROUTER_MAP";
    
        public static final String LAST_VERSION_NAME = "LAST_VERSION_NAME";
        public static final String LAST_VERSION_CODE = "LAST_VERSION_CODE";
    }
    

    可知此处 会一次性加载:

    • groupsIndex 分组路由
    • providersIndex provider路由
    • interceptorsIndex 所有的拦截器路由

    注解自动生成类示例

    image.png
    • ARouterRootapp 一共有几个分组
    /**
     * DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY AROUTER. */
    public class ARouter$$Root$$app implements IRouteRoot {
      @Override
      public void loadInto(Map<String, Class<? extends IRouteGroup>> routes) {
        routes.put("test", ARouter$$Group$$test.class);
        routes.put("yourservicegroupname", ARouter$$Group$$yourservicegroupname.class);
      }
    }
    
    

    ARouterGrouptest test组内的所有路由

    /**
     * DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY AROUTER. */
    public class ARouter$$Group$$test implements IRouteGroup {
      @Override
      public void loadInto(Map<String, RouteMeta> atlas) {
        atlas.put("/test/activity1", RouteMeta.build(RouteType.ACTIVITY, Test1Activity.class, "/test/activity1", "test", new java.util.HashMap<String, Integer>(){{put("ser", 9); put("ch", 5); put("fl", 6); put("dou", 7); put("boy", 0); put("url", 8); put("pac", 10); put("obj", 11); put("name", 8); put("objList", 11); put("map", 11); put("age", 3); put("height", 3); }}, -1, -2147483648));
        atlas.put("/test/activity2", RouteMeta.build(RouteType.ACTIVITY, Test2Activity.class, "/test/activity2", "test", new java.util.HashMap<String, Integer>(){{put("key1", 8); }}, -1, -2147483648));
        atlas.put("/test/activity3", RouteMeta.build(RouteType.ACTIVITY, Test3Activity.class, "/test/activity3", "test", new java.util.HashMap<String, Integer>(){{put("name", 8); put("boy", 0); put("age", 3); }}, -1, -2147483648));
        atlas.put("/test/activity4", RouteMeta.build(RouteType.ACTIVITY, Test4Activity.class, "/test/activity4", "test", null, -1, -2147483648));
        atlas.put("/test/fragment", RouteMeta.build(RouteType.FRAGMENT, BlankFragment.class, "/test/fragment", "test", null, -1, -2147483648));
        atlas.put("/test/webview", RouteMeta.build(RouteType.ACTIVITY, TestWebview.class, "/test/webview", "test", null, -1, -2147483648));
      }
    }
    
    

    yourservicegroupname 组内所有的路由信息

    public class ARouter$$Group$$yourservicegroupname implements IRouteGroup {
      @Override
      public void loadInto(Map<String, RouteMeta> atlas) {
        atlas.put("/yourservicegroupname/hello", RouteMeta.build(RouteType.PROVIDER, HelloServiceImpl.class, "/yourservicegroupname/hello", "yourservicegroupname", null, -1, -2147483648));
        atlas.put("/yourservicegroupname/json", RouteMeta.build(RouteType.PROVIDER, JsonServiceImpl.class, "/yourservicegroupname/json", "yourservicegroupname", null, -1, -2147483648));
        atlas.put("/yourservicegroupname/single", RouteMeta.build(RouteType.PROVIDER, SingleService.class, "/yourservicegroupname/single", "yourservicegroupname", null, -1, -2147483648));
      }
    }
    
    
    • ARouterProvidersapp 所有的Provider路由
    /**
     * DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY AROUTER. */
    public class ARouter$$Providers$$app implements IProviderGroup {
      @Override
      public void loadInto(Map<String, RouteMeta> providers) {
        providers.put("com.alibaba.android.arouter.demo.testservice.HelloService", RouteMeta.build(RouteType.PROVIDER, HelloServiceImpl.class, "/yourservicegroupname/hello", "yourservicegroupname", null, -1, -2147483648));
        providers.put("com.alibaba.android.arouter.facade.service.SerializationService", RouteMeta.build(RouteType.PROVIDER, JsonServiceImpl.class, "/yourservicegroupname/json", "yourservicegroupname", null, -1, -2147483648));
        providers.put("com.alibaba.android.arouter.demo.testservice.SingleService", RouteMeta.build(RouteType.PROVIDER, SingleService.class, "/yourservicegroupname/single", "yourservicegroupname", null, -1, -2147483648));
      }
    }
    
    • ARouterInterceptorsapp 所有的interceptor路由
    public class ARouter$$Interceptors$$app implements IInterceptorGroup {
      @Override
      public void loadInto(Map<Integer, Class<? extends IInterceptor>> interceptors) {
        interceptors.put(7, Test1Interceptor.class);
      }
    }
    
    

    4、内部核心类

    • ARouter - 核心逻辑的外观类,内部调用_ARouter
    • _ARouter - 内部ARouter的实现类,负责构造PostCard、navigation路由操作、拦截器处理。
    • LogisticsCenter 实现路由信息的加载和寻址(完善PostCard信息)

    具体的路由过程,可以分为两步:

    
    //(1)build() 通过path,构造出一个简易的PostCard对象,目前只包含分组和path信息
    Postcard postcard =    ARouter.getInstance()
                            .build("/test/activity2");
    //(2)调用navigation 去寻址。
    postcard.navigation();
                            
    

    我们具体看navigation 方法会进入ARouter.getInstance().navigation

    public Object navigation() {
            return navigation(null);
        }
    
        /**
         * Navigation to the route with path in postcard.
         *
         * @param context Activity and so on.
         */
        public Object navigation(Context context) {
            return navigation(context, null);
        }
    
        /**
         * Navigation to the route with path in postcard.
         *
         * @param context Activity and so on.
         */
        public Object navigation(Context context, NavigationCallback callback) {
            return ARouter.getInstance().navigation(context, this, -1, callback);
        }
    

    ARouter.navigation() 最终进入_ARouter.getInstance().navigation

    public final class ARouter {
     
    
        private ARouter() {
        }
    
       
        /**
         * Launch the navigation.
         *
         * @param mContext    .
         * @param postcard    .
         * @param requestCode Set for startActivityForResult
         * @param callback    cb
         */
        public Object navigation(Context mContext, Postcard postcard, int requestCode, NavigationCallback callback) {
            return _ARouter.getInstance().navigation(mContext, postcard, requestCode, callback);
        }
    }
    
    

    我们来看_ARouter的navigation方法

    protected Object navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
            PretreatmentService pretreatmentService = ARouter.getInstance().navigation(PretreatmentService.class);
           
    
            try {
                //(1)首先补全postcard中的路由信息,最终要的是要补全destination 对应的类信息
                LogisticsCenter.completion(postcard);
            } catch (NoRouteFoundException ex) {
                
                if (null != callback) {
                    callback.onLost(postcard);
                } else {
                    // No callback for this invoke, then we use the global degrade service.
                    DegradeService degradeService = ARouter.getInstance().navigation(DegradeService.class);
                    if (null != degradeService) {
                        degradeService.onLost(context, postcard);
                    }
                }
    
                return null;
            }
    
            if (null != callback) {
                callback.onFound(postcard);
            }
    
            //(2)然后是拦截器处理
            if (!postcard.isGreenChannel()) {   // It must be run in async thread, maybe interceptor cost too mush time made ANR.
                interceptorService.doInterceptions(postcard, new InterceptorCallback() {
                    /**
                     * Continue process
                     *
                     * @param postcard route meta
                     */
                    @Override
                    public void onContinue(Postcard postcard) {
                        _navigation(context, postcard, requestCode, callback);
                    }
    
                    /**
                     * Interrupt process, pipeline will be destory when this method called.
                     *
                     * @param exception Reson of interrupt.
                     */
                    @Override
                    public void onInterrupt(Throwable exception) {
                        if (null != callback) {
                            callback.onInterrupt(postcard);
                        }
    
                        logger.info(Consts.TAG, "Navigation failed, termination by interceptor : " + exception.getMessage());
                    }
                });
            } else {
                return _navigation(context, postcard, requestCode, callback);
            }
    
            retur
    

    (1)补全postcard中的路由信息,最重要的信息就是destination 路由对应的类信息和type 路由类型信息

     LogisticsCenter.completion(postcard);
    

    (2)处理拦截器

    遍历所有拦截器,如果被拦截,则回调onInterrupt

    interceptorService.doInterceptions(postcard, new InterceptorCallback() {
                  
                    @Override
                    public void onContinue(Postcard postcard) {
                        _navigation(context, postcard, requestCode, callback);
                    }
    
                   
                    @Override
                    public void onInterrupt(Throwable exception) {
                        if (null != callback) {
                            callback.onInterrupt(postcard);
                        }
    
                    }
    

    通过拦截器处理的路由 会调用:_navigation()

    
        private Object _navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
            final Context currentContext = null == context ? mContext : context;
    
            switch (postcard.getType()) {
                case ACTIVITY:
                    // Build intent
                    final Intent intent = new Intent(currentContext, postcard.getDestination());
                    intent.putExtras(postcard.getExtras());
    
                    // Set flags.
                    int flags = postcard.getFlags();
                    if (-1 != flags) {
                        intent.setFlags(flags);
                    } else if (!(currentContext instanceof Activity)) {    // Non activity, need less one flag.
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    }
    
                    // Set Actions
                    String action = postcard.getAction();
                    if (!TextUtils.isEmpty(action)) {
                        intent.setAction(action);
                    }
    
                    // Navigation in main looper.
                    runInMainThread(new Runnable() {
                        @Override
                        public void run() {
                            startActivity(requestCode, currentContext, intent, postcard, callback);
                        }
                    });
    
                    break;
                case PROVIDER:
                    return postcard.getProvider();
                case BOARDCAST:
                case CONTENT_PROVIDER:
                case FRAGMENT:
                    Class fragmentMeta = postcard.getDestination();
                    try {
                        Object instance = fragmentMeta.getConstructor().newInstance();
                        if (instance instanceof Fragment) {
                            ((Fragment) instance).setArguments(postcard.getExtras());
                        } else if (instance instanceof android.support.v4.app.Fragment) {
                            ((android.support.v4.app.Fragment) instance).setArguments(postcard.getExtras());
                        }
    
                        return instance;
                    } catch (Exception ex) {
                        logger.error(Consts.TAG, "Fetch fragment instance error, " + TextUtils.formatStackTrace(ex.getStackTrace()));
                    }
                case METHOD:
                case SERVICE:
                default:
                    return null;
            }
    
            return null;
        }
    
    

    可以看到:

    • type = Actvity,实际上是做的actvity跳转操作
    • type = Provider, 实际是返回一个Provider单例对象
    • type = Fragment,实际返回的是新创建的Fragment实例(非单例)

    三、AutoWired 参数自动注册是如何实现的

    @Route(path = "/test/activity1", name = "测试用 Activity")
    public class Test1Activity extends AppCompatActivity {
    
        @Autowired(desc = "姓名")
        String name = "jack";
    
        @Autowired
        int age = 10;
    
        @Autowired
        int height = 175;
    
        @Autowired(name = "boy", required = true)
        boolean girl;
     @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test1);
    
            ARouter.getInstance().inject(this);
        }
    }
    
    
    • 使用@Autowired 标记一个需要自动注入的参数,会自动生成一个Actvity名ARouterAutowired 类
    image.png
    public class Test1Activity$$ARouter$$Autowired implements ISyringe {
      private SerializationService serializationService;
    
      @Override
      public void inject(Object target) {
        serializationService = ARouter.getInstance().navigation(SerializationService.class);
        Test1Activity substitute = (Test1Activity)target;
        substitute.name = substitute.getIntent().getExtras() == null ? substitute.name : substitute.getIntent().getExtras().getString("name", substitute.name);
        substitute.age = substitute.getIntent().getIntExtra("age", substitute.age);
        substitute.height = substitute.getIntent().getIntExtra("height", substitute.height);
        substitute.girl = substitute.getIntent().getBooleanExtra("boy", substitute.girl);
        substitute.ch = substitute.getIntent().getCharExtra("ch", substitute.ch);
        substitute.fl = substitute.getIntent().getFloatExtra("fl", substitute.fl);
        substitute.dou = substitute.getIntent().getDoubleExtra("dou", substitute.dou);
        substitute.ser = (com.alibaba.android.arouter.demo.testinject.TestSerializable) substitute.getIntent().getSerializableExtra("ser");
        substitute.pac = substitute.getIntent().getParcelableExtra("pac");
        if (null != serializationService) {
          substitute.obj = serializationService.parseObject(substitute.getIntent().getStringExtra("obj"), new com.alibaba.android.arouter.facade.model.TypeWrapper<TestObj>(){}.getType());
        } else {
          Log.e("ARouter::", "You want automatic inject the field 'obj' in class 'Test1Activity' , then you should implement 'SerializationService' to support object auto inject!");
        }
        if (null != serializationService) {
          substitute.objList = serializationService.parseObject(substitute.getIntent().getStringExtra("objList"), new com.alibaba.android.arouter.facade.model.TypeWrapper<List<TestObj>>(){}.getType());
        } else {
          Log.e("ARouter::", "You want automatic inject the field 'objList' in class 'Test1Activity' , then you should implement 'SerializationService' to support object auto inject!");
        }
        if (null != serializationService) {
          substitute.map = serializationService.parseObject(substitute.getIntent().getStringExtra("map"), new com.alibaba.android.arouter.facade.model.TypeWrapper<Map<String, List<TestObj>>>(){}.getType());
        } else {
          Log.e("ARouter::", "You want automatic inject the field 'map' in class 'Test1Activity' , then you should implement 'SerializationService' to support object auto inject!");
        }
        substitute.url = substitute.getIntent().getExtras() == null ? substitute.url : substitute.getIntent().getExtras().getString("url", substitute.url);
        substitute.helloService = ARouter.getInstance().navigation(HelloService.class);
      }
    }
    
    

    其核心操作如下,就是从intent中提取参数,然后赋值到activity对应的变量上。

    Test1Activity substitute = (Test1Activity)target;
        substitute.name = substitute.getIntent().getExtras() == null ? substitute.name : substitute.getIntent().getExtras().getString("name", substitute.name);
    
    • 执行注入的方法
      ARouter.getInstance().inject(this);
    

    ARouter.java

     /**
         * Inject params and services.
         */
        public void inject(Object thiz) {
            _ARouter.inject(thiz);
        }
    
    

    _ARouter.java

     static void inject(Object thiz) {
            AutowiredService autowiredService = ((AutowiredService) ARouter.getInstance().build("/arouter/service/autowired").navigation());
            if (null != autowiredService) {
                autowiredService.autowire(thiz);
            }
        }
    
    

    从上面可知 最终调用进了_ARouter的inject方法,执行了AutowiredService的autowire()方法

    我们再看AutowiredService,它是Arouter内置的一个IProvider

    @Route(path = "/arouter/service/autowired")
    public class AutowiredServiceImpl implements AutowiredService {
        private LruCache<String, ISyringe> classCache;
        private List<String> blackList;
    
        @Override
        public void init(Context context) {
            classCache = new LruCache<>(66);
            blackList = new ArrayList<>();
        }
    
        @Override
        public void autowire(Object instance) {
            String className = instance.getClass().getName();
            try {
                if (!blackList.contains(className)) {
                    ISyringe autowiredHelper = classCache.get(className);
                    if (null == autowiredHelper) {  // No cache.
                        autowiredHelper = (ISyringe) Class.forName(instance.getClass().getName() + SUFFIX_AUTOWIRED).getConstructor().newInstance();
                    }
                    autowiredHelper.inject(instance);
                    classCache.put(className, autowiredHelper);
                }
            } catch (Exception ex) {
                blackList.add(className);    // This instance need not autowired.
            }
        }
    }
    
    

    其核心方法如下:

     autowiredHelper = (ISyringe) Class.forName(instance.getClass().getName() + SUFFIX_AUTOWIRED).getConstructor().newInstance();
       autowiredHelper.inject(instance);
    

    SUFFIX_AUTOWIRED 其实就是 ARouterAutowired

    以Test1Activity为例,最终效果就是找到自动创建的
    Test1ActivityARouterAutowired类,然后执行inject()

    相关文章

      网友评论

          本文标题:ARouter简单分析

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