4. Android 组件化四LiteRouter:为你的项目注入轻量高效的路由能力

前面我们学了阿里的Arouter,其实在没有Arouter之前,我已经有一套轻量级的路由框架LiteRouter! 下面我说说它的使用和原理,源码分析,整体架构!

1.如何实现跳转和通信

LiteRouter 采用的是 显式跳转 Activity 的方式,而非隐式调用。其核心原理是通过动态代理技术接口注解,在运行时直接构造目标 Activity 的显式 Intent 并执行跳转。

框架 跳转方式 核心机制 组件化支持
LiteRouterMini 隐式跳转 动态代理 + 接口注解 解耦调用方与目标 Activity
LiteRouter 显式跳转 动态代理 + 接口注解 解耦调用方与目标 Activity
ARouter 显式(映射类) 编译期注解 + 路由表生成 多模块路由合并

Android中通常的界面跳转指的是Activity控制器的处理,我们知道一般情况下需要知道要跳转的目标Activity,以及传递的参数内容等

2.LiteRouter设计思想:

Retrofit源码分析,动态代理,突然给了我灵感,App端的开发和后台的开发不就是独立的?那么,它们是如何互相"独立"最终又互相配合的呢?

显然是依靠我们的接口设计规约~ 那么如果我们也能像Retrofit那样,定义好Activity跳转的接口方法,然后调用此方法就能实现跳转,这岂不是就能解决我们的问题,于是LiteRouter诞生了~

中间通过动态代理进行封装和实现! 前面学设计模式的时候,学习了动态代理;[ ](10.Android 设计模式 核心模式之四动态代理 在商业项目中的落地Android动态代理利用Java的`ja - 掘金)

3.LiteRouter的使用

less 复制代码
LiteRouter liteRouter = new LiteRouter.Builder().interceptor(new Interceptor() {
    @Override
    public boolean intercept(IntentWrapper intentWrapper) {
        return false;
    }
}).build();
final IntentService intentService = liteRouter.create(IntentService.class, ActivityA.this);
IntentWrapper intentWrapper = intentService.intent2ActivityDemo2Raw("android", 2016);
// intent
Intent intent = intentWrapper.getIntent();
// add your flags
intentWrapper.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
// start
intentWrapper.start();

// 3.接口的定义
public interface IntentService {
    @ClassName("com.example.module_a.ActivityA")
    @RequestCode(100)
    void intent2ActivityDemo2(@Key("platform") String platform, @Key("year") int year);

    @ClassName("com.example.module_b.ActivityB")
    IntentWrapper intent2ActivityDemo2Raw(@Key("platform") String platform, @Key("year") int year);
}

4.LiteRouter 实现原理

4.1 详细的源码分析

4.1.1 代理

typescript 复制代码
/**
 * 轻量级路由框架核心类
 * 通过动态代理实现声明式页面跳转
 */
public final class LiteRouter {
    // 路由拦截器实例
    private Interceptor interceptor;

    /**
     * 私有构造方法
     * @param interceptor 路由拦截器实例
     */
    LiteRouter(Interceptor interceptor) {
        this.interceptor = interceptor;
    }

    /**
     * 创建路由接口的动态代理实例
     * 
     * @param service  路由接口类(需包含跳转声明方法)
     * @param context  上下文对象(用于启动Activity)
     * @param <T>      路由接口类型
     * @return         路由接口的代理实现
     */
    public <T> T create(final Class<T> service, final Context context) {
        // 使用动态代理拦截接口方法调用
        return (T) Proxy.newProxyInstance(
            service.getClassLoader(), 
            new Class<?>[] { service },
            new InvocationHandler() {
                @Override 
                public Object invoke(Object proxy, Method method, Object... args) throws Throwable {
                    // 1. 构建跳转包装对象
                    IntentWrapper intentWrapper = loadIntentWrapper(context, method, args);
                    
                    // 2. 根据方法返回类型处理跳转逻辑
                    Class returnType = method.getReturnType();
                    
                    // 返回void类型:直接执行跳转
                    if (returnType == void.class) {
                        // 检查拦截器:若未被拦截则执行跳转
                        if (interceptor == null || !interceptor.intercept(intentWrapper)) {
                            intentWrapper.start();
                        }
                        return null;
                    }
                    // 返回IntentWrapper类型:返回包装对象供后续操作
                    else if (returnType == IntentWrapper.class) {
                        return intentWrapper;
                    }
                    // 不支持其他返回类型
                    throw new RuntimeException("Method return type only support 'void' or 'IntentWrapper'");
                }
            });
    }

    /**
     * 构建跳转意图包装对象
     * 
     * @param context 上下文对象
     * @param method  被调用的接口方法
     * @param args    方法参数
     * @return        配置完成的IntentWrapper实例
     */
    IntentWrapper loadIntentWrapper(Context context, Method method, Object... args) {
        // 使用建造者模式构造跳转对象
        return new IntentWrapper.Builder(context, method, args).build();
    }

    /**
     * 建造者模式:配置LiteRouter实例
     */
    public static final class Builder {
        private Interceptor interceptor;

        /**
         * 设置路由拦截器
         * 
         * @param interceptor 拦截器实现
         * @return Builder实例(链式调用)
         */
        public Builder interceptor(Interceptor interceptor) {
            this.interceptor = interceptor;
            return this;
        }

        /**
         * 构建LiteRouter实例
         * 
         * @return 配置完成的LiteRouter实例
         */
        public LiteRouter build() {
            return new LiteRouter(interceptor);
        }
    }
}

4.1.2 包装类

scss 复制代码
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.SparseArray;

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;

/**
 * Intent跳转封装类
 * 负责构建Intent对象并执行页面跳转操作
 */
public class IntentWrapper {
    private int mFlags;             // Intent标志位
    private Context mContext;       // 上下文对象
    private Bundle mExtras;         // 附加数据Bundle
    private String mClassName;      // 目标Activity类名
    private int mRequestCode = -1;  // startActivityForResult请求码(-1表示普通跳转)
    private Intent mIntent;         // 构建的Intent对象

    /**
     * 构造方法
     * 
     * @param context     上下文
     * @param className   目标Activity完整类名
     * @param extras      附加数据Bundle
     * @param flags       Intent标志位
     * @param requestCode startActivityForResult请求码
     */
    IntentWrapper(Context context, String className, Bundle extras, int flags, int requestCode) {
        mFlags = flags;
        mContext = context;
        mExtras = extras;
        mClassName = className;
        mRequestCode = requestCode;

        // 构建Intent并设置参数
        mIntent = new Intent();
        mIntent.setClassName(mContext, mClassName);  // 显式设置组件
        mIntent.putExtras(mExtras);                  // 添加额外数据
        mIntent.addFlags(mFlags);                    // 添加标志位
    }

    // ------------------------- 基础访问方法 -------------------------
    public String getClassName() {
        return mClassName;
    }

    public void setClassName(String newClassName) {
        mIntent.setClassName(mContext, newClassName);
    }

    public Bundle getExtras() {
        return mExtras;
    }

    public Intent getIntent() {
        return mIntent;
    }

    public Context getContext() {
        return mContext;
    }

    public void addFlags(int flags) {
        mIntent.addFlags(flags);
    }

    // ------------------------- 跳转执行方法 -------------------------
    /**
     * 智能跳转(自动判断是否使用requestCode)
     */
    public void start() {
        if (mRequestCode == -1) {
            startActivity();
        } else {
            startActivityForResult(mRequestCode);
        }
    }

    /**
     * 普通Activity跳转
     * 非Activity上下文自动添加FLAG_ACTIVITY_NEW_TASK
     */
    public void startActivity() {
        if (!(mContext instanceof Activity)) {
            mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        mContext.startActivity(mIntent);
    }

    /**
     * 带返回结果的Activity跳转
     * 
     * @param requestCode 请求码
     * @throws RuntimeException 上下文非Activity时抛出异常
     */
    public void startActivityForResult(int requestCode) {
        if (!(mContext instanceof Activity)) {
            throw new RuntimeException("startActivityForResult only works for activity context");
        }
        ((Activity) mContext).startActivityForResult(mIntent, requestCode);
    }

    // ------------------------- Builder建造者类 -------------------------
    /**
     * IntentWrapper建造者类
     * 负责解析路由方法注解和参数
     */
    public static final class Builder {
        private int mFlags;          // 标志位累加值
        private Context mContext;    // 上下文
        private Method mMethod;     // 路由接口方法
        private Object[] mArgs;      // 方法参数值
        private String mClassName;  // 目标类名(从注解解析)
        private int mRequestCode;    // 请求码(从注解解析)

        public Builder(Context context, Method method, Object... args) {
            mContext = context;
            mMethod = method;
            mArgs = args;
        }

        /**
         * 添加Intent标志位(支持多次调用)
         * 
         * @param flags Intent标志位
         * @return Builder实例(链式调用)
         */
        public Builder addFlags(int flags) {
            mFlags |= flags;  // 使用位或运算累加标志位
            return this;
        }

        /**
         * 构建IntentWrapper实例
         * 
         * @return 配置完成的IntentWrapper对象
         * @throws RuntimeException 缺少必要注解或参数解析失败时抛出
         */
        public IntentWrapper build() {
            // 1. 解析方法级别注解(@ClassName, @RequestCode)
            Annotation[] methodAnnotations = mMethod.getAnnotations();
            for (Annotation annotation : methodAnnotations) {
                parseMethodAnnotation(annotation);
            }
            
            // 校验类名注解必须存在
            if (TextUtils.isEmpty(mClassName)) {
                throw new RuntimeException("ClassName annotation is required.");
            }
            
            // 2. 解析方法参数
            Type[] types = mMethod.getGenericParameterTypes();        // 获取参数类型
            Annotation[][] paramAnnotations = mMethod.getParameterAnnotations(); // 获取参数注解
            Bundle bundleExtra = new Bundle();  // 存储参数的Bundle
            
            // 遍历所有参数
            for (int i = 0; i < types.length; i++) {
                String key = null;
                // 查找@Key注解获取参数键名
                for (Annotation ann : paramAnnotations[i]) {
                    if (ann instanceof Key) {
                        key = ((Key) ann).value();
                        break;
                    }
                }
                // 解析并存储参数到Bundle
                parseParameter(bundleExtra, types[i], key, mArgs[i]);
            }
            
            // 3. 构建IntentWrapper
            boolean hasRequestCode = mMethod.isAnnotationPresent(RequestCode.class);
            return new IntentWrapper(
                mContext, 
                mClassName, 
                bundleExtra, 
                mFlags,
                hasRequestCode ? mRequestCode : -1  // 有@RequestCode注解时使用解析值
            );
        }

        /**
         * 解析方法参数并存入Bundle
         * 
         * @param bundleExtra 存储Bundle
         * @param type        参数类型(支持泛型)
         * @param key         参数键名(可能为null)
         * @param arg         参数实际值
         */
        void parseParameter(Bundle bundleExtra, Type type, String key, Object arg) {
            // 获取原始类型(擦除泛型)
            Class<?> rawType = getRawType(type);
            
            // 基础类型处理
            if (rawType == String.class) {
                bundleExtra.putString(key, arg.toString());
            } 
            // 其他基础类型处理(int, long, boolean等)...
            else if (rawType == Bundle.class) {
                // Bundle特殊处理:支持合并或单独存储
                if (TextUtils.isEmpty(key)) {
                    bundleExtra.putAll((Bundle) arg);
                } else {
                    bundleExtra.putBundle(key, (Bundle) arg);
                }
            } 
            // SparseArray<Parcelable>处理
            else if (rawType == SparseArray.class) {
                // 泛型校验:必须实现Parcelable
                if (type instanceof ParameterizedType) {
                    ParameterizedType pt = (ParameterizedType) type;
                    Type itemType = pt.getActualTypeArguments()[0];  // 获取泛型类型
                    
                    if (itemType instanceof Class && 
                        Parcelable.class.isAssignableFrom((Class<?>) itemType)) {
                        // 安全类型转换
                        @SuppressWarnings("unchecked")
                        SparseArray<Parcelable> sparseArray = (SparseArray<Parcelable>) arg;
                        bundleExtra.putSparseParcelableArray(key, sparseArray);
                    } else {
                        throw new RuntimeException("SparseArray的泛型必须实现Parcelable接口");
                    }
                } else {
                    throw new RuntimeException("SparseArray必须指定泛型类型");
                }
            } 
            // ArrayList处理(支持String/Integer/Parcelable等)
            else if (rawType == ArrayList.class) {
                // 泛型校验
                if (type instanceof ParameterizedType) {
                    ParameterizedType pt = (ParameterizedType) type;
                    Type itemType = pt.getActualTypeArguments()[0];  // 获取列表项类型
                    
                    if (itemType == String.class) {
                        bundleExtra.putStringArrayList(key, (ArrayList<String>) arg);
                    } 
                    // 其他ArrayList类型处理...
                    else if (itemType instanceof Class && 
                             Parcelable.class.isAssignableFrom((Class<?>) itemType)) {
                        // 安全类型转换
                        @SuppressWarnings("unchecked")
                        ArrayList<Parcelable> list = (ArrayList<Parcelable>) arg;
                        bundleExtra.putParcelableArrayList(key, list);
                    } else {
                        throw new RuntimeException("ArrayList的泛型必须是String/Integer/Parcelable");
                    }
                } else {
                    throw new RuntimeException("ArrayList必须指定泛型类型");
                }
            } 
            // 其他复杂类型处理(Parcelable数组、Serializable等)...
            else if (rawType.isArray() && Parcelable.class.isAssignableFrom(rawType.getComponentType())) {
                bundleExtra.putParcelableArray(key, (Parcelable[]) arg);
            } 
            // 实现Parcelable接口的对象
            else if (Parcelable.class.isAssignableFrom(rawType)) {
                bundleExtra.putParcelable(key, (Parcelable) arg);
            } 
            // 实现Serializable接口的对象
            else if (Serializable.class.isAssignableFrom(rawType)) {
                bundleExtra.putSerializable(key, (Serializable) arg);
            } 
            // 无法识别的类型
            else {
                throw new RuntimeException("Bundle不支持的类型, 参数: " + key);
            }
        }

        /**
         * 解析方法注解
         * 
         * @param annotation 方法上的注解
         */
        void parseMethodAnnotation(Annotation annotation) {
            // 解析@ClassName注解
            if (annotation instanceof ClassName) {
                mClassName = ((ClassName) annotation).value();
            } 
            // 解析@RequestCode注解
            else if (annotation instanceof RequestCode) {
                mRequestCode = ((RequestCode) annotation).value();
            }
        }

        /**
         * 获取Type对应的原始Class类型
         * 
         * @param type Java类型(支持泛型)
         * @return 擦除泛型后的原始Class
         */
        Class<?> getRawType(Type type) {
            // 类型擦除实现(参考Retrofit设计)
            if (type instanceof Class) {
                return (Class<?>) type;
            } else if (type instanceof ParameterizedType) {
                return (Class<?>) ((ParameterizedType) type).getRawType();
            } else if (type instanceof GenericArrayType) {
                Type componentType = ((GenericArrayType) type).getGenericComponentType();
                return Array.newInstance(getRawType(componentType), 0).getClass();
            } else if (type instanceof TypeVariable) {
                return Object.class;  // 泛型变量默认Object
            } else if (type instanceof WildcardType) {
                return getRawType(((WildcardType) type).getUpperBounds()[0]);
            } else {
                throw new IllegalArgumentException("不支持的Type类型: " + type.getClass());
            }
        }
    }
}

4.2 实现Activity的跳转的原理

1).通过注解定义跳转的接口

2).动态代理,代理接口的实现

3).封装跳转的参数,进行显示跳转

4.3 LiteRouter 实现接口的调用

java 复制代码
import android.content.Context;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

/**
 * 扩展的 LiteRouter - 支持模块间接口调用
 */
public class LiteRouter {
    // 服务注册表(存储接口实现)
    private static final Map<Class<?>, Object> serviceRegistry = new HashMap<>();
    
    // 服务缓存(存储代理对象)
    private static final Map<Class<?>, Object> serviceProxyCache = new HashMap<>();
    
    /**
     * 注册服务实现
     * 
     * @param serviceInterface 服务接口类
     * @param implementation   服务实现实例
     * @param <T>              服务接口类型
     */
    public static <T> void registerService(Class<T> serviceInterface, T implementation) {
        serviceRegistry.put(serviceInterface, implementation);
        serviceProxyCache.remove(serviceInterface); // 清除缓存
    }
    
    /**
     * 获取服务接口
     * 
     * @param serviceInterface 服务接口类
     * @param <T>              服务接口类型
     * @return 服务实现代理
     */
    public static <T> T getService(Class<T> serviceInterface) {
        // 检查是否已有缓存代理
        if (serviceProxyCache.containsKey(serviceInterface)) {
            return serviceInterface.cast(serviceProxyCache.get(serviceInterface));
        }
        
        // 创建动态代理
        Object proxy = Proxy.newProxyInstance(
            serviceInterface.getClassLoader(),
            new Class<?>[]{serviceInterface},
            new ServiceInvocationHandler(serviceInterface)
        );
        
        // 缓存代理对象
        serviceProxyCache.put(serviceInterface, proxy);
        return serviceInterface.cast(proxy);
    }
    
    /**
     * 服务调用处理器
     */
    private static class ServiceInvocationHandler implements InvocationHandler {
        private final Class<?> serviceInterface;
        
        public ServiceInvocationHandler(Class<?> serviceInterface) {
            this.serviceInterface = serviceInterface;
        }
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 获取实际服务实现
            Object implementation = serviceRegistry.get(serviceInterface);
            
            if (implementation == null) {
                throw new IllegalStateException("服务未注册: " + serviceInterface.getName());
            }
            
            // 调用实际方法
            return method.invoke(implementation, args);
        }
    }
    
    // 原有Activity跳转功能保持不变
    // ... (保留之前实现的Activity跳转功能)
}

步骤1: 定义公共接口(在公共模块)

arduino 复制代码
// 用户服务接口
public interface UserService {
    String getUserName();
    void updateUserProfile(String name, int age);
}

步骤2: 在B模块实现接口并注册

typescript 复制代码
public class UserServiceImpl implements UserService {
    @Override
    public String getUserName() {
        return "John Doe";
    }
    
    @Override
    public void updateUserProfile(String name, int age) {
        // 实际更新逻辑
    }
}

// B模块初始化
public class ModuleBInitializer {
    public static void init(Context context) {
        // 注册服务实现
        LiteRouter.registerService(UserService.class, new UserServiceImpl());
        LiteRouter.registerService(PaymentService.class, new PaymentServiceImpl());
        
        // 注册Activity路由(可选)
        // ...
    }
}

步骤3: 在A模块调用接口

java 复制代码
public class ModuleAClass {
    public void performOperations() {
        // 获取用户服务
        UserService userService = LiteRouter.getService(UserService.class);
        
        // 调用方法
        String userName = userService.getUserName();
        userService.updateUserProfile("Jane Smith", 30);
    }
    
    // 使用Activity跳转功能
    public void navigateToSettings(Context context) {
        LiteRouter liteRouter = new LiteRouter.Builder().build();
        IntentService intentService = liteRouter.create(IntentService.class, context);
        intentService.openSettings().start();
    }
}

4.4 LiteRouter 实现拦截器的原理

LiteRouter 支持全局拦截器,可在跳转前统一处理逻辑(如登录校验、权限检查)

kotlin 复制代码
LiteRouter router = new LiteRouter.Builder()
    .interceptor(intentWrapper -> {
        if (needLogin) {
            intentWrapper.setClassName(LoginActivity.class.getName()); // 重定向到登录页
            return true; // 拦截并修改跳转
        }
        return false; // 放行
    })
    .build();

拦截器通过 IntentWrapper 对象获取或修改跳转信息,实现灵活控制1。

4.5 整体的架构图

4.5.1 通过 LiteRouter.create(IntentService.class, context) 创建接口实例时,框架内部使用 动态代理技术(类似 Retrofit):

  • 当调用接口方法(如 jumpToDemo)时,代理对象拦截方法调用;
  • 解析方法上的注解,提取目标 Activity 类名、请求码、参数键名;
  • 根据参数值构建 Intent,并自动填充数据;
  • 最终通过 startActivity()startActivityForResult() 执行跳转

4.5.2 、路由注册与发现

  • 无集中式路由表 :与需预注册路由表的框架(如 ARouter)不同,LiteRouter 无需预先扫描或生成路由映射 ,而是通过接口方法中的 @ClassName 直接指定目标类。
  • 组件化解耦:调用方仅依赖接口,而非具体 Activity 类。业务模块独立开发时,只要接口定义一致,即使目标 Activity 实现变更,调用方也无需修改代码1。

核心类:

LiteRouter

IntentWrapper

5.LiteRouter MINI版本:基于 URI 的隐式跳转机制实现

java 复制代码
import android.content.Intent;
import android.net.Uri;
import android.util.Base64;
import android.util.Log;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 * 路由工厂类 - 基于动态代理实现的路由框架核心
 * 
 * 功能:
 * 1. 通过接口定义路由路径和参数
 * 2. 自动将方法调用转换为隐式 Intent
 * 3. 支持 GET/POST 两种请求方式
 * 4. 自动处理查询参数(@Query)和请求体(@Body)
 * 
 * 使用步骤:
 * 1. 定义路由接口(使用 GET/POST 注解)
 * 2. 使用 RouterFactory.create() 创建路由实例
 * 3. 调用接口方法获取 Intent
 * 4. 使用 startActivity() 启动目标界面
 */
public class RouterFactory {

    /**
     * 创建路由服务实例
     * 
     * @param service 路由接口类(必须包含 GET/POST 注解的方法)
     * @param <T>     路由接口类型
     * @return 路由服务代理实例
     */
    @SuppressWarnings("unchecked")
    public static <T> T create(Class<T> service) {
        // 使用 Java 动态代理技术创建接口实例
        return (T) Proxy.newProxyInstance(
                service.getClassLoader(),   // 使用接口的类加载器
                new Class<?>[]{service},   // 代理的接口列表
                new RouterInvocationHandler() // 自定义调用处理器
        );
    }

    /**
     * 路由调用处理器 - 实现方法调转到 Intent 的转换逻辑
     */
    private static class RouterInvocationHandler implements InvocationHandler {
        
        /**
         * 处理路由接口方法调用
         * 
         * @param proxy  代理对象
         * @param method 调用的方法
         * @param args   方法参数
         * @return 构建好的 Intent 对象
         * @throws Throwable 路由构建过程中的异常
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 1. 解析方法注解(确定请求类型和路径)
            GET getAnnotation = method.getAnnotation(GET.class);
            POST postAnnotation = method.getAnnotation(POST.class);
            
            // 检查是否配置了路由注解
            if (getAnnotation == null && postAnnotation == null) {
                String errorMsg = "方法 " + method.getName() + " 缺少 @GET 或 @POST 路由注解";
                Log.e("RouterFactory", errorMsg);
                throw new IllegalArgumentException(errorMsg);
            }
            
            // 获取注解中定义的路由路径
            String path = getAnnotation != null ? getAnnotation.value() : postAnnotation.value();
            
            // 2. 构建基础URI (scheme://authority/path)
            Uri.Builder uriBuilder = new Uri.Builder()
                    .scheme("app")      // 自定义协议头
                    .authority("router") // 路由标识
                    .path(path);        // 目标路径
            
            // 3. 处理查询参数 (@Query注解)
            processQueryParameters(method, args, uriBuilder);
            
            // 4. 处理POST请求体 (@Body注解)
            if (postAnnotation != null) {
                processRequestBody(method, args, uriBuilder);
            }
            
            // 5. 构建最终Intent
            Uri finalUri = uriBuilder.build();
            Log.d("RouterFactory", "构建路由URI: " + finalUri.toString());
            
            return new Intent(Intent.ACTION_VIEW, finalUri)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 确保可在非Activity上下文启动
        }

        /**
         * 处理方法参数的 @Query 注解
         * 
         * @param method      当前方法
         * @param args        方法参数值
         * @param uriBuilder URI构建器
         */
        private void processQueryParameters(Method method, Object[] args, Uri.Builder uriBuilder) {
            // 获取方法所有参数的注解
            Annotation[][] parameterAnnotations = method.getParameterAnnotations();
            
            for (int i = 0; i < parameterAnnotations.length; i++) {
                for (Annotation annotation : parameterAnnotations[i]) {
                    if (annotation instanceof Query) {
                        // 获取注解中定义的参数名
                        String key = ((Query) annotation).value();
                        
                        // 获取参数值并转换为字符串
                        String value = args[i] != null ? args[i].toString() : null;
                        
                        if (value != null) {
                            // 添加到URI的查询参数
                            uriBuilder.appendQueryParameter(key, value);
                        }
                    }
                }
            }
        }

        /**
         * 处理 @Body 注解参数(POST请求专用)
         * 
         * @param method      当前方法
         * @param args        方法参数值
         * @param uriBuilder URI构建器
         */
        private void processRequestBody(Method method, Object[] args, Uri.Builder uriBuilder) {
            Annotation[][] parameterAnnotations = method.getParameterAnnotations();
            
            for (int i = 0; i < parameterAnnotations.length; i++) {
                for (Annotation annotation : parameterAnnotations[i]) {
                    if (annotation instanceof Body) {
                        // 将对象序列化为JSON
                        String json = new Gson().toJson(args[i]);
                        
                        // 使用Base64编码避免特殊字符问题
                        String encoded = Base64.encodeToString(
                                json.getBytes(StandardCharsets.UTF_8),
                                Base64.URL_SAFE | Base64.NO_WRAP
                        );
                        
                        // 添加到特殊查询参数
                        uriBuilder.appendQueryParameter("_data", encoded);
                        Log.d("RouterFactory", "Body数据已编码: " + json);
                    }
                }
            }
        }
    }
}

这个路由框架实现了基于 URI 的隐式跳转机制,核心优势在于解耦调用方和目标界面,通过动态代理自动处理参数传递,适合需要支持深层链接(Deep Link)的场景。

手写的LiteRouter项目地址:github.com/pengcaihua1...

相关推荐
周某人姓周1 分钟前
xss作业
前端·xss
归于尽10 分钟前
为什么你的 React 项目越改越乱?这 3 个配置细节藏着答案
前端·react.js
JiaLin_Denny27 分钟前
javascript 中数组对象操作方法
前端·javascript·数组对象方法·数组对象判断和比较
代码老y28 分钟前
Vue3 从 0 到 ∞:Composition API 的底层哲学、渲染管线与生态演进全景
前端·javascript·vue.js
LaoZhangAI37 分钟前
ComfyUI集成GPT-Image-1完全指南:8步实现AI图像创作革命【2025最新】
前端·后端
LaoZhangAI38 分钟前
Cline + Gemini API 完整配置与使用指南【2025最新】
前端·后端
Java&Develop42 分钟前
防止电脑息屏 html
前端·javascript·html
Maybyy1 小时前
javaScript中数组常用的函数方法
开发语言·前端·javascript
国王不在家1 小时前
组件-多行文本省略-展开收起
前端·javascript·html