到目前为止,相信市面上大多数android开发人员都有使用过阿里ARouter在自己的项目中,那么ARouter是如何实现解耦的呢?下面我们来实现一个简版的ARouter路由(HRouter)。

  • 首先创建两个java Libray

java 路由设计 java router_android

java 路由设计 java router_android_02

hrouter_annotations:为创建注解使用

hrouter-complier:为注册注解处理器使用
  • 创建注解类Route
//声明注解是放在什么上面的(这里是放在类上面的)
@Target(ElementType.TYPE)
//声明注解存在的周期(编译时注解: 默认的保留策略,注解会在class字节码文件中存在)
@Retention(RetentionPolicy.CLASS)
public @interface Route {
    String value();
}
  • 配置hrouter-complier
在hrouter-complier的gradle中引入auto-service和hrouter_annotations

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    // AS-3.4.1 + geadles5.1.1-all+ auto-service:1.0-rc6
    annotationProcessor 'com.google.auto.service:auto-service:1.0-rc6'
    compileOnly 'com.google.auto.service:auto-service:1.0-rc6'
    //3.4及其以下
    //implementation 'com.google.auto.service:auto-service:1.0-rc6'

    implementation project(path: ':hrouter_annotations')
}
//中文乱码问题(错误:编码GBK不可映射字符)
tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}
  • 注册注解处理器(这是核心步奏,会生成我们所需要的代码)
首先将你的activity或Fragment添加注解

@Route("login/login")
public class LoginActivity extends AppCompatActivity {
    ...
}

@Route("member/blankfragment")
public class BlankFragment extends Fragment {
    ...
}

创建我们的注册类annotationCompiler 继承BaseProcessor并添加@AutoService(Processor.class)注解

package com.hxg.hrouter_complier;
import com.google.auto.service.AutoService;
import com.hxg.hrouter_annotations.Route;
import com.hxg.hrouter_complier.entity.ClazzType;
import com.hxg.hrouter_complier.entity.ElementType;
import com.hxg.hrouter_complier.utils.LogUtil;

import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;


//注册注解处理器
@AutoService(Processor.class)
public class annotationCompiler extends BaseProcessor {

    Writer writer;
    String utilName;
    private LogUtil logUtil;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        //得到写代码的类
        try {
            if (null==moduleName){
                throw new RuntimeException("build.gradle中未完成配置AROUTER_MODULE_NAME,请查看您module中build.gradle的配置");
            }
            utilName = "HRouter$$Processor$$" + moduleName;
            writer = filer.createSourceFile("com.hxg.android.hrouter.routes." + utilName).openWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        logUtil = new LogUtil(filer,moduleName);
        logUtil.writerLog("模块名称:" + moduleName);
    }


    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        //得到所有HRouter下面的类节点
        Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(Route.class);
        //创建集合 来结构化数据
        Map<String, ElementType> map = new HashMap<>();
        //遍历  得到每一个类节点(Acticity)
        for (Element element : elements) {
            TypeElement typeElement = (TypeElement) element;
            //得到类的包名加类名
            String activityName = typeElement.getQualifiedName().toString();
            String key = typeElement.getAnnotation(Route.class).value();
            if (isActivity(typeElement)) {
                ElementType elementType = new ElementType();
                elementType.setClazz(activityName + ".class");
                elementType.setType(ClazzType.ACTIVITY);
                map.put(key, elementType);
            } else if (isFragment(typeElement)) {
                ElementType elementType = new ElementType();
                elementType.setClazz(activityName + ".class");
                elementType.setType(ClazzType.FRAGMENT);
                map.put(key, elementType);
            }
        }
        if (map.size() > 0) {
            try {
                writer.write("package com.hxg.android.hrouter.routes;\n" +
                        "\n" +
                        "import com.hxg.lib_hrouter.HRouter;\n" +
                        "import com.hxg.lib_hrouter.IRouter;\n" +
                        "\n" +
                        "public class " + utilName + " implements IRouter {\n" +
                        "@Override\n" +
                        " public void putClazz() {\n");
                Iterator<String> iterator = map.keySet().iterator();
                while (iterator.hasNext()) {
                    String key = iterator.next();
                    ElementType elementType = map.get(key);
                    writer.write("HRouter.getInstance().addClazz(\"" + key + "\",\"" + elementType.getType() + "\"," + elementType.getClazz() + ");\n");
                }
                writer.write("}\n}");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (writer != null) {
                    try {
                        writer.flush();
                        writer.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        logUtil.finallyLog();
        return false;
    }


}

代码中可以看到我们使用writer手动生成一个"HRouter\$\$Processor\$\$" + moduleName类,类中装在了我们添加注解的Activity和Fragment

moduleName为我们的module的名称

android {
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [AROUTER_MODULE_NAME: project.getName()]
            }
        }
    }
}
  • 我们annotationCompiler需要的其他类如下:
package com.hxg.hrouter_complier;

import com.hxg.hrouter_annotations.Route;
import com.hxg.hrouter_complier.utils.Consts;

import java.util.HashSet;
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.lang.model.SourceVersion;
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 com.hxg.hrouter_complier.utils.Consts.KEY_MODULE_NAME;

public abstract class BaseProcessor extends AbstractProcessor {
    //生成文件的对象
    protected Filer filer;
    protected Elements elementUtils;
    protected Types types;
    protected String moduleName;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        filer = processingEnvironment.getFiler();
        types = processingEnv.getTypeUtils();
        elementUtils = processingEnvironment.getElementUtils();
        Map<String, String> options = processingEnv.getOptions();
        if (options != null) {
            moduleName = options.get(KEY_MODULE_NAME);
        }
    }

    /**
     * 声明这个注解处理器要识别处理的注解
     *
     * @return
     */
    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> annotations = new HashSet<>();
        annotations.add(Route.class.getCanonicalName());
        return annotations;
    }

    /**
     * 支持java的源版本
     *
     * @return
     */
    @Override
    public SourceVersion getSupportedSourceVersion() {
        return processingEnv.getSourceVersion();
    }

    //判断当前是不是activity类
    protected boolean isActivity(TypeElement typeElement) {
        TypeMirror activityTm = elementUtils.getTypeElement(Consts.ACTIVITY).asType();
        if (types.isSubtype(typeElement.asType(), activityTm)) return true;
        return false;
    }

    //判断当前类是fragment
    protected boolean isFragment(TypeElement typeElement) {
        TypeMirror fragmentTm = elementUtils.getTypeElement(Consts.FRAGMENT).asType();
        TypeMirror fragmentTmV4 = elementUtils.getTypeElement(Consts.FRAGMENT_V4).asType();
        if (types.isSubtype(typeElement.asType(), fragmentTm)
                || types.isSubtype(typeElement.asType(), fragmentTmV4)) {
            return true;
        }
        return false;
    }
}
package com.hxg.hrouter_complier.entity;

public class ClazzType {
    public static final String ACTIVITY = "activity";
    public static final String FRAGMENT = "fragment";
}
package com.hxg.hrouter_complier.entity;

public class ElementType {
    private String clazz;
    private String type;
    public String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    public String toString() {
        return "ElementType{" +
                ", clazz='" + clazz + '\'' +
                ", type=" + type +
                '}';
    }
}
package com.hxg.hrouter_complier.utils;

public class Consts {
    public static final String ACTIVITY = "android.app.Activity";
    public static final String FRAGMENT = "android.app.Fragment";
    public static final String FRAGMENT_V4 = "android.support.v4.app.Fragment";


    public static final String KEY_MODULE_NAME = "AROUTER_MODULE_NAME";
}
package com.hxg.hrouter_complier.utils;

import java.io.IOException;
import java.io.Writer;

import javax.annotation.processing.Filer;

public class LogUtil {
    Writer writer;
    String utilName;

    public LogUtil(Filer filer, String moduleName) {
        utilName = "HRouter$$LogUtil$$" + moduleName;
        try {
            writer = filer.createSourceFile("com.hxg.android.hrouter.log." + utilName).openWriter();
            writer.write("package com.hxg.android.hrouter.log;\n" +
                    "\n" +
                    "import android.util.Log;\n" +
                    "import com.hxg.lib_hrouter.ILog;\n" +
                    "\n" +
                    "public class " + utilName + " implements ILog {\n" +
                    "@Override\n" +
                    "public void logPrint() {\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public void writerLog(String logString) {
        try {
            writer.write(" Log.i(\"HRouter" + "\",\"" + logString + "\");\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void finallyLog() {
        if (writer != null) {
            try {
                writer.write("}\n}");
                writer.flush();
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

到这里我们编译生成的类基本完成,不出意外,编译或运行一下我们项目会生成对应的代码(有个IRouter接口后面会提到)

java 路由设计 java router_java_03

package com.hxg.android.hrouter.routes;

import com.hxg.lib_hrouter.HRouter;
import com.hxg.lib_hrouter.IRouter;

public class HRouter$$Processor$$module_member implements IRouter {
@Override
 public void putClazz() {
HRouter.getInstance().addClazz("member/blankfragment","fragment",com.hxg.module_member.BlankFragment.class);
HRouter.getInstance().addClazz("member/member","activity",com.hxg.module_member.MemberActivity.class);
}
}
  • 执行生成的类
    如何调用呢?因为上面生成的类的包名是我们自己所起,因此我们可以根据通过包名获取这个包下面的所有类名
/**
     * 通过包名获取这个包下面的所有类名
     *
     * @param packageName
     * @return
     */
    private List<String> getClassName(String packageName) {
        //创建一个class对象集合
        List<String> classList = new ArrayList<>();
        String path = null;
        try {
            //通过包管理器   获取到应用信息类然后获取到APK的完整路径
            path = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0).sourceDir;
            //根据APK的完整路径获取到编译后的dex文件目录
            DexFile dexfile = new DexFile(path);
            //获得编译后的dex文件中的所有class
            Enumeration<String> entries = dexfile.entries();
            //然后进行遍历
            while (entries.hasMoreElements()) {
                //通过遍历所有的class的包名
                String name = entries.nextElement();
                //判断类的包名是否符合我们起的包名(com.hxg.util)
                if (name.contains(packageName)) {
                    //如果符合,就添加到集合中
                    classList.add(name);
                }
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return classList;
    }

这样就可以拿到包下所有的类了,然后判断判断这个类是不是实现了IRouter接口找到生成的类,再通过接口的引用调用其生成的方法

//根据包名获取到这个包下面所有的类名
        List<String> classList = getClassName("com.hxg.android.hrouter.routes");
        //遍历
        for (String s : classList) {
            try {
                Class<?> aClass = Class.forName(s);
                //判断这个类是不是IRouter这个接口的子类
                if (IRouter.class.isAssignableFrom(aClass)) {
                    //通过接口的引用  指向子类的实例
                    IRouter iRouter = (IRouter) aClass.newInstance();
                    iRouter.putClazz();
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
        }

下是完整的实现代码 ,首先我们创建一个android Library

java 路由设计 java router_java 路由设计_04

完整的实现类

package com.hxg.lib_hrouter;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;

import com.hxg.lib_hrouter.contextprovider.HAppUtils;
import com.hxg.lib_hrouter.entity.ElementType;
import com.hxg.lib_hrouter.facade.Postcard;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import dalvik.system.DexFile;

/**
 * 桥梁
 */
public class HRouter {
    private static Handler mHandler;
    private Context context;
    //装在所有Activity类对象的容器
    private Map<String, ElementType> map;


    private HRouter() {
        map = new HashMap<>();
    }

    public void init(Context context) {
        this.context = context;
        mHandler = new Handler(Looper.getMainLooper());
        //根据包名获取到这个包下面所有的类名
        List<String> classList = getClassName("com.hxg.android.hrouter.routes");
        //遍历
        for (String s : classList) {
            try {
                Class<?> aClass = Class.forName(s);
                //判断这个类是不是IRouter这个接口的子类
                if (IRouter.class.isAssignableFrom(aClass)) {
                    //通过接口的引用  指向子类的实例
                    IRouter iRouter = (IRouter) aClass.newInstance();
                    iRouter.putClazz();
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
        }
        if (HAppUtils.isApkInDebug()) {
            List<String> classLogList = getClassName("com.hxg.android.hrouter.log");
            //遍历
            for (String s : classLogList) {
                try {
                    Class<?> aClass = Class.forName(s);
                    //判断这个类是不是ILog这个接口的子类
                    if (ILog.class.isAssignableFrom(aClass)) {
                        //通过接口的引用  指向子类的实例
                        ILog iLog = (ILog) aClass.newInstance();
                        iLog.logPrint();
                    }
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static HRouter getInstance() {
        return HrouterHolder.sInstance;
    }

    private static class HrouterHolder {

        private static final HRouter sInstance = new HRouter();
    }

    public Map<String, ElementType> getMap() {
        return map;
    }

    /**
     * 将Activity,Fragment加入到map中的方法
     *
     * @param key
     * @param clazz
     */
    public void addClazz(String key, String clazzType, Class clazz) {
        if (key != null && clazz != null) {
            ElementType elementType = new ElementType();
            elementType.setType(clazzType);
            elementType.setClazz(clazz);
            map.put(key, elementType);
        }
    }

    public Postcard build(String path) {
        if (TextUtils.isEmpty(path)) {
            throw new RuntimeException("HRouter 传入地址不能为空!");
        }
        return new Postcard(context, path);
    }

    /**
     * 跳转Activity的方法
     *
     * @param currentContext
     * @param intent
     * @param requestCode
     */
    public void navigation(final Context currentContext, final Intent intent, final int requestCode) {
        if (!(currentContext instanceof Activity)) {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        runInMainThread(new Runnable() {
            @Override
            public void run() {
                startActivity(currentContext, intent, requestCode);
            }
        });
    }

    /**
     * 跳转Activity的方法
     *
     * @param currentContext
     * @param intent
     * @param requestCode
     */
    private void startActivity(Context currentContext, Intent intent, int requestCode) {
        if (requestCode >= 0) {
            if (currentContext instanceof Activity) {
                ((Activity) currentContext).startActivityForResult(intent, requestCode);
            } else {
                currentContext.startActivity(intent);
            }
        } else {
            currentContext.startActivity(intent);
        }

    }

    /**
     * 通过包名获取这个包下面的所有类名
     *
     * @param packageName
     * @return
     */
    private List<String> getClassName(String packageName) {
        //创建一个class对象集合
        List<String> classList = new ArrayList<>();
        String path = null;
        try {
            //通过包管理器   获取到应用信息类然后获取到APK的完整路径
            path = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0).sourceDir;
            //根据APK的完整路径获取到编译后的dex文件目录
            DexFile dexfile = new DexFile(path);
            //获得编译后的dex文件中的所有class
            Enumeration<String> entries = dexfile.entries();
            //然后进行遍历
            while (entries.hasMoreElements()) {
                //通过遍历所有的class的包名
                String name = entries.nextElement();
                //判断类的包名是否符合我们起的包名(com.hxg.util)
                if (name.contains(packageName)) {
                    //如果符合,就添加到集合中
                    classList.add(name);
                }
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return classList;
    }

    private void runInMainThread(Runnable runnable) {
        if (Looper.getMainLooper().getThread() != Thread.currentThread()) {
            mHandler.post(runnable);
        } else {
            runnable.run();
        }
    }
}

ILog接口(主要是为了在注解生成器生成代码的时保存log日志的,无实际作用)

package com.hxg.lib_hrouter;

public interface ILog {
    void logPrint();
}

IRouter接口

package com.hxg.lib_hrouter;

public interface IRouter {
    void putClazz();
}

Postcard(封装了参数和跳转接口)

package com.hxg.lib_hrouter.facade;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;

import com.hxg.lib_hrouter.HRouter;
import com.hxg.lib_hrouter.utils.SerializationUtil;

import java.io.Serializable;
import java.util.ArrayList;


public class Postcard extends RouteMeta {
    private Intent mIntent;
    private Context mContext;

    public Postcard(Context context, String path) {
        this.mContext = context;
        this.mPath = path;
        if (getDestination() != null) {
            this.mIntent = new Intent(mContext, getDestination());
        }
    }


    public Object navigation() {
        if (getDestination() != null) {
            HRouter.getInstance().navigation(mContext, mIntent, 0);
            return 1;
        }
        if (getFragment() != null) {
            try {
                return getFragment().newInstance();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
        }
        return -1;
    }


    public Object navigation(Activity currentContext, int requestCode) {
        if (getDestination() != null) {
            HRouter.getInstance().navigation(currentContext, mIntent, requestCode);
            return 1;
        }
        return -1;
    }

    public Postcard with(Bundle bundle) {
        if (null != bundle && getDestination() != null) {
            mIntent.putExtras(bundle);
        }
        return this;
    }

    public Postcard withObject(String key, Object value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, SerializationUtil.object2Json(value));
        }
        return this;
    }

    public Postcard withString(String key, String value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }

    public Postcard withBoolean(String key, boolean value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }

    public Postcard withShort(String key, short value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }

    public Postcard withInt(String key, int value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }

    public Postcard withLong(String key, long value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }

    public Postcard withDouble(String key, double value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }

    public Postcard withByte(String key, byte value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }

    public Postcard withChar(String key, char value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }

    public Postcard withFloat(String key, float value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }

    public Postcard withCharSequence(String key, CharSequence value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }

    public Postcard withParcelable(String key, Parcelable value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }

    public Postcard withParcelableArray(String key, Parcelable[] value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }

    public Postcard withParcelableArrayList(String key, ArrayList<? extends Parcelable> value) {
        if (getDestination() != null) {
            mIntent.putParcelableArrayListExtra(key, value);
        }
        return this;
    }

    public Postcard withIntegerArrayList(String key, ArrayList<Integer> value) {
        if (getDestination() != null) {
            mIntent.putIntegerArrayListExtra(key, value);
        }
        return this;
    }

    public Postcard withStringArrayList(String key, ArrayList<String> value) {
        if (getDestination() != null) {
            mIntent.putStringArrayListExtra(key, value);
        }
        return this;
    }

    public Postcard withCharSequenceArrayList(String key, ArrayList<CharSequence> value) {
        if (getDestination() != null) {
            mIntent.putCharSequenceArrayListExtra(key, value);
        }
        return this;
    }


    public Postcard withSerializable(String key, Serializable value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }


    public Postcard withByteArray(String key, byte[] value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }


    public Postcard withShortArray(String key, short[] value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }


    public Postcard withCharArray(String key, char[] value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }


    public Postcard withFloatArray(String key, float[] value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }


    public Postcard withCharSequenceArray(String key, CharSequence[] value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }


    public Postcard withBundle(String key, Bundle value) {
        if (getDestination() != null) {
            mIntent.putExtra(key, value);
        }
        return this;
    }

}

RouteMeta(Postcard父类)

package com.hxg.lib_hrouter.facade;

import android.app.Activity;

import com.hxg.lib_hrouter.HRouter;
import com.hxg.lib_hrouter.entity.ElementType;
import com.hxg.lib_hrouter.utils.HToastUtil;

public class RouteMeta {
    protected String mPath;

    public RouteMeta() {
    }

    protected Class<? extends Activity> getDestination() {
        ElementType elementType = HRouter.getInstance().getMap().get(mPath);
        if (elementType == null) {
            HToastUtil.showToast("未找到" + mPath + "配置的类名");
            return null;
        }
        if (elementType.getType().equals("activity")) {
            Class<? extends Activity> clazz = elementType.getClazz();
            return clazz;
        }
        return null;
    }

    protected Class getFragment() {
        ElementType elementType = HRouter.getInstance().getMap().get(mPath);
        if (elementType == null) {
            HToastUtil.showToast("未找到" + mPath + "配置的类名");
            return null;
        }
        if (elementType.getType().equals("fragment")) {
            Class<? extends Activity> clazz = elementType.getClazz();
            return clazz;
        }
        return null;
    }

}

ElementType(封装数据)

package com.hxg.lib_hrouter.entity;

public class ElementType {
    private Class clazz;
    private String type;

    public Class getClazz() {
        return clazz;
    }

    public void setClazz(Class clazz) {
        this.clazz = clazz;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    public String toString() {
        return "ElementType{" +
                "clazz=" + clazz +
                ", type='" + type + '\'' +
                '}';
    }
}

其他

package com.hxg.lib_hrouter.utils;

import android.content.Context;
import android.widget.Toast;

import com.hxg.lib_hrouter.contextprovider.HRouterContextProvider;

public class HToastUtil {
    private static Toast toast;

    /**
     * 静态吐司
     *
     * @param context
     * @param text
     */
    public static void showToast(Context context, String text) {
        if (toast == null) {
            toast = Toast.makeText(context, text, Toast.LENGTH_SHORT);
        }
        toast.setText(text);
        toast.show();
    }

    /**
     * 不需要上下文对象的  静态toast
     */
    public static void showToast(String text) {
        showToast(HRouterContextProvider.get().getApplication(), text);
    }
}
package com.hxg.lib_hrouter.utils;


import com.google.gson.Gson;

public class SerializationUtil {
    public static String object2Json(Object value) {
        return new Gson().toJson(value);
    }
}

到这里 我们的调用处理逻辑基本完成,在你的Application中调用HRouter.init(Context context);方法就可以完成注册了,当然我这里使用的 ContentProvider无侵入式获取context时进行注册的

public class HRouterAppContentProvider extends ContentProvider {
    static Context mContext;

    @Override
    public boolean onCreate() {
        mContext = getContext();
        //初始化全局Context提供者
        HRouter.getInstance().init(getContext().getApplicationContext());
        HRouterContextProvider.get();
        return false;
    }
    ...
}

关于无侵入式获取context请看:

  • 使用
implementation project(path: ':lib_hrouter')
  implementation project(path: ':hrouter_annotations')
  annotationProcessor project(path: ':hrouter-complier')
Router.getInstance().build("member/member").navigation();

到这里我们我们的HRouter路由就基本完成了!


HRouter使用教程

引用方法

allprojects {

    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
    
}

android {
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [AROUTER_MODULE_NAME: project.getName()]
            }
        }
    }
}

dependencies {
    // Replace with the latest version
    implementation 'com.github.huangxiaoguo1:HRouter:?'
    annotationProcessor 'com.github.huangxiaoguo1.HRouter:hrouter-complier:?'
    ...
}

添加导航注解

@Route("login/login")
public class LoginActivity extends AppCompatActivity {
    ...
}


@Route("member/blankfragment")
public class BlankFragment extends Fragment {
    ...
}

跳转Activity

Router.getInstance().build("member/member").navigation();

跳转Activity并传参

HRouter.getInstance()
       .build("login/login")
       .withString("login", "我是测试带过来的数据")
       .withInt("login1", 321)
       .withObject("object", new LoginTest("huangxiaoguo", 18))
       .navigation();

跳转Activity并返回

HRouter.getInstance()
                .build("login/login")
                .navigation(this, 666);

获得Fragment

Fragment fragment = (Fragment) HRouter.getInstance().build("member/blankfragment").navigation();