必须使用@retention(runtime)和@target(parameter)声明注解,通过method.getparameterannotations()安全获取二维注解数组,校验存在性后再提取实例,禁止setaccessible(true)或调用私有成员,并在主线程预校验uri、超时等语义合法性。

在多媒体异步处理框架中,用反射提取方法参数上的注解是常见需求,比如用于自动绑定媒体源路径、校验参数合法性、或注入编解码配置。但必须兼顾功能性和安全性——不能因反射滥用破坏沙箱隔离、绕过访问控制,也不能因注解缺失或类型错误导致运行时崩溃。
确保注解在运行期可用
只有声明为 @Retention(RetentionPolicy.RUNTIME) 的注解才能被反射读取。若注解只保留到源码(SOURCE)或字节码(CLASS)阶段,getParameterAnnotations() 将返回空数组或 null。
- 自定义注解必须显式指定
@Retention(RUNTIME)和@Target(PARAMETER) - 避免混用
@Target({METHOD, PARAMETER})却未在参数位置实际使用——反射不会报错,但逻辑可能误判 - 框架启动时可做一次注解元数据校验:扫描关键处理器类,检查目标方法参数是否确实标注了预期注解
通过 Method.getParameterAnnotations() 安全获取
Method 对象提供了 Annotation[][] getParameterAnnotations() 方法,它返回一个二维数组:外层数组按参数声明顺序排列,内层数组是该参数上所有注解的实例。
- 不要直接调用
Class.getAnnotation()或Field.getAnnotation()——它们不适用于参数级注解 - 遍历前先校验
method != null且method.isAccessible() == false(默认不可访问,无需手动设为 true) - 对每个
Annotation[] paramAnns,用isAnnotationPresent(Class)判断是否存在某类注解,再用getAnnotation(Class)获取实例,避免空指针
限制反射访问范围,防止越权操作
多媒体框架常运行在受限环境(如 Android 沙箱、插件化容器),需规避反射带来的安全风险。
- 禁止通过反射调用非 public 参数类型构造器或 setter——仅读取注解元数据,不触发对象创建或状态修改
- 不使用
setAccessible(true)强行访问私有参数或其字段;参数本身是局部变量,反射无法直接操作其值,重点应放在“读注解”而非“改参数” - 若框架需兼容部分信任环境(如 WebView 插件),应在反射前检查
SecurityManager是否存在,并捕获SecurityException做降级处理(例如跳过注解解析,走默认配置)
结合注解内容做轻量级预校验
提取到注解后,别急着交给异步线程执行。可在主线程或调度层做简单语义校验,提升健壮性。
- 检查
@MediaUri(value = "...")中的 URI 是否符合 scheme 规则(如file://、content://、http://) - 验证
@Timeout(millis = 5000)的值是否在合理区间(如 100–30000 毫秒),避免传入负数或超大值导致线程挂起 - 对多个同类型注解(如多个
@AudioChannel),检查数量是否超出设备支持通道数,提前失败而非异步中抛异常











