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

相关推荐
崔庆才丨静觅13 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606114 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了14 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅14 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅15 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅15 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment15 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅15 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊15 小时前
jwt介绍
前端
爱敲代码的小鱼15 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax