Unity安卓应用JNI报错:Unknown signature for type 'AlarmReceiver'求助
解决Unity安卓开发中JNI: Unknown signature for type 'AlarmReceiver'错误
错误原因
你在创建Intent时传入了C#的AlarmReceiver类型(typeof(AlarmReceiver)),但Android系统的Intent需要的是Java层BroadcastReceiver的完整类路径,而非C#侧的AndroidJavaProxy代理类类型。JNI无法识别C#类型的签名,因此抛出该错误。
解决方案
Android系统无法直接调度C#层的AndroidJavaProxy实现的广播接收器,必须通过Java原生BroadcastReceiver中转,再触发C#逻辑。以下是完整修复步骤:
1. 创建Android原生BroadcastReceiver
在Unity项目的Plugins/Android/com/yourpackage目录下(需自行创建对应包名路径),新建AlarmReceiver.java文件:
package com.yourpackage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import com.unity3d.player.UnityPlayer; public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if ("Server_Managment_Background_Processes".equals(action)) { // 调用Unity中指定GameObject的C#方法 UnityPlayer.UnitySendMessage("AlarmManagerHelperObject", "OnAlarmTriggered", ""); } } }
2. 注册BroadcastReceiver到AndroidManifest
在Plugins/Android目录下创建AndroidManifest.xml(若已有则修改),添加接收器注册:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.yourpackage"> <application> <receiver android:name=".AlarmReceiver"> <intent-filter> <action android:name="Server_Managment_Background_Processes" /> </intent-filter> </receiver> </application> </manifest>
3. 修正C#代码
更新AlarmManagerHelper,移除原C#侧的AlarmReceiver类,改为接收原生广播的回调:
using UnityEngine; using System; public class AlarmManagerHelper : MonoBehaviour { public static AlarmManagerHelper Instance; private Action pendingAlarmAction; private void Start() { Instance = this; DontDestroyOnLoad(gameObject); } public void ScheduleAlarm(float delayInSeconds, Action action) { pendingAlarmAction = action; long triggerTime = DateTime.Now.AddSeconds(delayInSeconds).Ticks / 10000; AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"); AndroidJavaObject alarmManager = currentActivity.Call<AndroidJavaObject>("getSystemService", "alarm"); // 创建指向原生广播的Intent AndroidJavaObject alarmIntent = new AndroidJavaObject("android.content.Intent", "Server_Managment_Background_Processes"); int requestCode = UnityEngine.Random.Range(0, int.MaxValue); AndroidJavaClass pendingIntentClass = new AndroidJavaClass("android.app.PendingIntent"); // Android 12+需指定FLAG_IMMUTABLE,避免兼容性问题 AndroidJavaObject pendingIntent = pendingIntentClass.CallStatic<AndroidJavaObject>("getBroadcast", currentActivity, requestCode, alarmIntent, 1 << 25); // 使用setExact保证触发时间准确性(API 19+) alarmManager.Call("setExact", 0, triggerTime, pendingIntent); } // 供Android原生调用的回调方法,需与UnitySendMessage参数匹配 public void OnAlarmTriggered(string unused) { pendingAlarmAction?.Invoke(); pendingAlarmAction = null; } }
关键注意事项
- 确保挂载
AlarmManagerHelper的GameObject名称为AlarmManagerHelperObject(与UnitySendMessage的第一个参数一致),且该对象不会被场景销毁。 - Android 12及以上版本创建
PendingIntent必须指定FLAG_IMMUTABLE(值为1 << 25)或FLAG_MUTABLE,否则会抛出安全异常。 - 若需要调度多个不同的闹钟任务,可通过Intent传递额外参数(如任务ID),在C#侧区分执行不同Action。
内容的提问来源于stack exchange,提问作者Adam Marshall
相关产品推荐
相关产品推荐

