理解Arouter,实现Arouter基础功能

一 使用注解在编译时将路径的数据封装在RouteMeta类中 并且在实现IRouteGroup类中 添加到参数atlas map中

特殊的类
@AutoService(Processor.class) 主要的作用是注解 processor类,并对其生成 META-INF 的配置信息。
javapoet 帮助生成代码
IRouteGroup 生成的类实现了此接口 便于在运行时使用封装的数据

二 初始化Arouter时 通过反射调用自动生成的类(继承自IRouteGroup)的loadInto 方法把路径和对应的类保存到缓存中

  ((IRouteRoot) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.groupsIndex);
  className : 自动生成的类的路径
  Warehouse.groupsIndex  : 缓存的map

三 Arouter跳转

通过path路径去缓存中找到对应的类做跳转


*为什么要分成两个依赖module*  

    因为annotationProcessor project(':lib')  只参与编译

    在android中写注解一般分两个module,一个是专门存放的注解类比如叫apt-lib,一个是注解解释类比如叫apt-process,后一个依赖前一个。apt-lib提供api要打入apk的,apt-process只参与编译。 
    apt-process中的build.gradle 

    compile project(':apt-lib') 

    app中的build.gradle 

    compile project(":apt-lib") 
    annotationProcessor project(':apt-process') 

创建步骤

一 创建
创建注解 java module:arouter_annotaion 创建route注解 RouteMeta封装类

创建编译时 java module : aroter_compiler 创建AutowiredProcessor类
需要引入
implementation ‘com.google.auto.service:auto-service:1.0-rc2’ //@AutoService(Processor.class) 调用
implementation ‘com.squareup:javapoet:1.7.0’ //帮助自动生成java类的依赖
需要依赖 arouter_annotaion module

   processor里面主要两个方法
     init()  初始化一些方法
     process()  解析注解 自动生成java类

创建api调用 android module : arouter_appi 创建出事Arouter类 IRouteGroup接口
需要依赖 arouter_annotaion module

二 使用

在app中引用上面三种module
annotationProcessor project(':aroter_compiler')
implementation project(':arouter_annotaion')
implementation project(':arouter_appi')

在aplication中 初始化
 Arouter.getInstance().init(getApplication());
在需要的页面添加路由
  @Route(path = "ThreeActivity")
调用 Arouter.getInstance().build("ThreeActivity");

项目结构
这里写图片描述

这里写图片描述

这里写图片描述

相关类
arouter_annotaion module

package com.example.aroter_compiler;

import com.example.arouter_annotaion.Route;
import com.example.arouter_annotaion.RouteMeta;
import com.google.auto.service.AutoService;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeSpec;

import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;

import static javax.lang.model.element.Modifier.PUBLIC;

/**
 * Created by qf on 2018/7/25
 * 描述: AutowiredProcessor
 */
@AutoService(Processor.class)
public class AutowiredProcessor extends AbstractProcessor {


    private Filer mFiler;
    private Types mTypeUtils;
    private Elements mElementUtils;
    // System interface
    public static final String ACTIVITY = "android.app.Activity";

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        //初始化一些工具类
        mTypeUtils = processingEnv.getTypeUtils();
        mElementUtils = processingEnv.getElementUtils();
        mFiler = processingEnv.getFiler();
    }

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        System.out.println("ele====activity_");
        if (null != roundEnvironment) {
            Set<? extends Element> elementsAnnotatedWith = roundEnvironment.getElementsAnnotatedWith(Route.class);
            doElements(elementsAnnotatedWith);
            return true;
        }
        return false;
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> annotations = new LinkedHashSet<>();
        annotations.add(Route.class.getCanonicalName());
        return annotations;
    }


    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }

    private void doElements(Set<? extends Element> elementsAnnotatedWith) {
        TypeMirror activityMirror = mElementUtils.getTypeElement(ACTIVITY).asType();


        //定义参数
        ParameterizedTypeName inputMapTypeOfGroup = ParameterizedTypeName.get(
                ClassName.get(Map.class),
                ClassName.get(String.class),
                ClassName.get(RouteMeta.class)
        );
        ParameterSpec groupParamSpec = ParameterSpec.builder(inputMapTypeOfGroup, "atlas").build();


        //定义方法
        MethodSpec.Builder loadIntoMethodOfGroupBuilder = MethodSpec.methodBuilder("loadInto")
                .addAnnotation(Override.class)
                .addModifiers(PUBLIC)
                .addParameter(groupParamSpec);

        ClassName routeMetaCn = ClassName.get(RouteMeta.class);


        for (Element ele : elementsAnnotatedWith) {

            if (mTypeUtils.isSubtype(ele.asType(), activityMirror)) {
                System.out.println("ele====activity_" + ele.getSimpleName());
                Route annotation = ele.getAnnotation(Route.class);
                String path = annotation.path();
                ClassName className = ClassName.get((TypeElement) ele);


                /**
                 * atlas.put("/test/activity1", RouteMeta.build(RouteType.ACTIVITY, Test1Activity.class, "/test/activity1", "test", new java.util.HashMap<String, Integer>(){{put("pac", 9); put("ch", 5); put("fl", 6); put("obj", 10); put("name", 8); put("dou", 7); put("boy", 0); put("objList", 10); put("map", 10); put("age", 3); put("url", 8); put("height", 3); }}, -1, -2147483648));
                 */
                loadIntoMethodOfGroupBuilder.addStatement(
                        "atlas.put($S, $T.build($T.class))",
                        path,
                        routeMetaCn,
                        className);
            }
            System.out.println("ele====" + ele.getSimpleName());
        }

        System.out.println("ele====over====");
        try {
            JavaFile.builder(
                    "com.qf.routes2",
                    TypeSpec.classBuilder("creteBySelf")
                            // doc
                            //.addJavadoc(WARNING_TIPS)
                            .addSuperinterface(ClassName.get(mElementUtils.getTypeElement("com.example.arouter_appi.IRouteGroup")))
                            .addModifiers(PUBLIC)
                            .addMethod(loadIntoMethodOfGroupBuilder.build())
                            .build()
            ).build().writeTo(mFiler);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

arouter_annotaion module

package com.example.arouter_annotaion;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by qf on 2018/7/25
 * 描述: Route
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface Route {
    String path();
}
package com.example.arouter_annotaion;



/**
 * It contains basic route information.
 *
 * @author Alex <a href="mailto:zhilong.liu@aliyun.com">Contact me.</a>
 * @version 1.0
 * @since 16/8/24 09:45
 */
public class RouteMeta {

    private Class<?> destination;   // Destination
    private String path;            // Path of route


    public RouteMeta(Class<?> cla) {
        this.destination = cla;
    }

    public RouteMeta(){}


    public Class<?> getDestination() {
        return destination;
    }

    public void setDestination(Class<?> destination) {
        this.destination = destination;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public static RouteMeta build(Class<?> destination) {
        return new RouteMeta(destination);
    }

}

arouter_appi module

package com.example.arouter_appi;

import android.app.Application;
import android.content.Intent;
import android.widget.Toast;

import com.example.arouter_annotaion.RouteMeta;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by qf on 2018/7/25
 * 描述: Arouter
 */
public class Arouter {

    private static Arouter arouter;

    public static Map<String, RouteMeta> arouters = new HashMap<>();

    private static Application mContext;

//    ARouter.getInstance().build("/simple/simple1Activity").navigation();

    private Arouter(){}

    public static Arouter  getInstance() {
        if (null == arouter) {
            arouter = new Arouter();
        }
        return arouter;
    }


    public void init(Application context) {
        mContext = context;
        try {
            ((IRouteGroup) (Class.forName("com.qf.routes2.creteBySelf").getConstructor().newInstance())).loadInto(arouters);

            Toast.makeText(mContext, arouters.size() + "", Toast.LENGTH_SHORT).show();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }



    public void build(String path) {
        RouteMeta routeMeta = arouters.get(path);
        if (null == routeMeta) return;

        Class<?> destination = routeMeta.getDestination();
        if (null != destination) {
            Intent intent = new Intent(mContext, destination);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mContext.startActivity(intent);
        }
    }


}
package com.example.arouter_appi;

import com.example.arouter_annotaion.RouteMeta;

import java.util.Map;

/**
 * Created by qf on 2018/7/25
 * 描述: IRouteGroup
 */
public interface IRouteGroup {
    /**
     * Fill the atlas with routes in group.
     */
    void loadInto(Map<String, RouteMeta> atlas);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值