使用Java反射调用PackageManager时遇“Expected Receiver of Type”错误求助
解决Java反射调用PackageManager方法的类型错误
错误原因
你遇到的Expected receiver of type android.content.pm.PackageManager, but got java.lang.Class<android.content.pm.PackageManager>错误,核心问题是:getInstalledApplications是PackageManager的实例方法,调用时需要传入PackageManager的具体实例,但你传给invoke的是Class<PackageManager>对象,类型不匹配。
修复步骤
- 获取PackageManager实例:在Android中,必须通过Context对象调用
getPackageManager()获取PackageManager的实例,不能直接用Class对象替代。 - 修正invoke的接收者参数:将
invoke的第一个参数从c(Class对象)替换为PackageManager实例。 - 补全版本兼容逻辑:原代码只处理了API33+的情况,低版本会导致
m为null,需要补充else分支处理旧版本的方法签名。
修正后的代码示例
// 先获取Context对象,比如在Activity中直接用this,或通过其他合法方式获取 Context context = ...; PackageManager pm = context.getPackageManager(); Class<?> c = pm.getClass(); // 也可以用Class.forName("android.content.pm.PackageManager") Method m = null; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) { m = c.getMethod("getInstalledApplications", PackageManager.ApplicationInfoFlags.class); } else { // 处理API33以下版本,方法参数为int类型 m = c.getMethod("getInstalledApplications", int.class); } m.setAccessible(true); List<ApplicationInfo> output; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) { // API33+需传入ApplicationInfoFlags类型参数 output = (List<ApplicationInfo>) m.invoke(pm, PackageManager.ApplicationInfoFlags.of(PackageManager.GET_META_DATA)); } else { // 低版本传入int类型flag output = (List<ApplicationInfo>) m.invoke(pm, PackageManager.GET_META_DATA); }
关键说明
- 实例方法反射规则:
Method.invoke(Object receiver, Object... args)中,receiver必须是方法所属类的实例,只有静态方法才允许传Class对象或null。 - Android版本适配:API33开始
getInstalledApplications的参数从int改为ApplicationInfoFlags,必须分别处理两种参数类型,否则会出现方法找不到的错误。
内容的提问来源于stack exchange,提问作者localacct
相关产品推荐
相关产品推荐

