Unity安卓插件onPostExecute推送通知时遇致命异常
先看你遇到的错误日志:
04-04 15:30:39.876 8765-8765/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.akgames.kazzan, PID: 8765 java.lang.NoSuchMethodError: No direct method
(Landroid/content/Context;Ljava/lang/String;)V in class Landroid/support/v4/app/NotificationCompat$Builder; or its super classes (declaration of 'android.support.v4.app.NotificationCompat$Builder' appears in /data/app/com.akgam...
这个问题我做Unity Android插件时也踩过坑,核心就是NotificationCompat.Builder构造方法版本不匹配,或者Unity打包时依赖库冲突导致运行时找不到正确的方法。给你几个实用的解决步骤:
1. 确认构造方法的版本兼容性
带Context和channelId参数的NotificationCompat.Builder(Context context, String channelId)构造方法是从**Android O(API 26)**开始引入的,属于较新的Support库或AndroidX版本。如果你的插件代码用了这个构造,但Unity打包时引入的是旧版Support库(比如低于26.0.0的support-v4),就会触发这个错误。
- 若需要兼容API26以下设备:可以分版本处理,代码示例如下:
NotificationCompat.Builder builder; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // API26+使用带channelId的构造,同时先创建通知渠道 builder = new NotificationCompat.Builder(context, channelId); NotificationChannel channel = new NotificationChannel(channelId, "通知渠道名称", NotificationManager.IMPORTANCE_DEFAULT); NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); manager.createNotificationChannel(channel); } else { // 旧版本用不带channelId的构造 builder = new NotificationCompat.Builder(context); } - 若只兼容API26+:直接确保项目依赖支持该构造的库版本(比如support-v4:26.0.0及以上,或AndroidX的core库)。
2. 统一Unity项目的Android依赖库版本
Unity默认自带的Support库版本可能和你插件里的不一致,打包时会出现依赖冲突,导致运行时加载了旧版本的NotificationCompat.Builder类。
方案A:切换到AndroidX(推荐)
现在Google已弃用旧Support库,改用AndroidX,Unity支持也很完善:
- 打开Unity的
Player Settings > Player > Publishing Settings > Build - 勾选
Custom Main Gradle Template和Custom Base Gradle Template - 打开生成的
mainTemplate.gradle,在dependencies块添加AndroidX依赖:dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) // 可根据需求调整版本号 implementation 'androidx.core:core:1.10.1' implementation 'androidx.appcompat:appcompat:1.6.1' // 其他项目依赖... } - 在
gradle.properties中添加:
Jetifier会自动将旧Support库依赖转换为AndroidX版本,避免冲突。android.useAndroidX=true android.enableJetifier=true
方案B:统一旧Support库版本
如果暂时不想切换到AndroidX,确保插件和Unity用的Support库版本一致:
- 找到Unity安装目录下的Support库版本(比如
Editor/Data/PlaybackEngines/AndroidPlayer/Variations/mono/Release/Classes/libs/support-v4.jar),确认其版本号 - 在插件的
build.gradle中修改依赖为对应版本,并用compileOnly避免重复打包:dependencies { compileOnly 'com.android.support:support-v4:28.0.0' // 替换为Unity对应的版本 }
3. 检查插件的打包方式
如果你的Android插件是aar/jar格式,若里面包含了Support库类,会和Unity自带版本冲突。解决方法:
- 在插件的
build.gradle中,将Support库依赖从implementation改为compileOnly,这样打包时不会包含Support库代码,运行时直接使用Unity项目里的版本。
4. 确保onPostExecute中的Context有效
虽然这不是方法找不到的直接原因,但AsyncTask的onPostExecute里获取的Context可能失效(比如Activity已销毁),可以尝试用Unity提供的上下文:
Context context = UnityPlayer.currentActivity;
内容的提问来源于stack exchange,提问作者alp

