阿里ARouter路由核心原理(打造一个自己的路由)

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 getSupportedAnnotationTypes() {

Set 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 L o g U t i l LogUtil 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接口后面会提到)

在这里插入图片描述

package com.hxg.android.hrouter.routes;

import com.hxg.lib_hrouter.HRouter;

import com.hxg.lib_hrouter.IRouter;

public class HRouter P r o c e s s o r Processor Processormodule_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 getClassName(String packageName) {

//创建一个class对象集合

List 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 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 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

在这里插入图片描述

完整的实现类

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 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 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 getClassName(String packageName) {

//创建一个class对象集合

List 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 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 value) {

if (getDestination() != null) {

mIntent.putIntegerArrayListExtra(key, value);

}

return this;

}

public Postcard withStringArrayList(String key, ArrayList value) {

if (getDestination() != null) {

mIntent.putStringArrayListExtra(key, value);

}

return this;

}

public Postcard withCharSequenceArrayList(String key, ArrayList 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 + ‘’’ +

‘}’;

}

}

其他

总结

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节

还有 高级架构技术进阶脑图、Android开发面试专题资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

一线互联网面试专题

379页的Android进阶知识大全

379页的Android进阶知识大全

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。祝大家2021年万事大吉。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
turn 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 + ‘’’ +

‘}’;

}

}

其他

总结

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节

还有 高级架构技术进阶脑图、Android开发面试专题资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

[外链图片转存中…(img-Sq09qUQ8-1715422202916)]

[外链图片转存中…(img-KBxGSfaZ-1715422202916)]

[外链图片转存中…(img-nEsd7m1j-1715422202917)]

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。祝大家2021年万事大吉。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值