Unity 调用 Android Java 原生方法可以通过 C# 反射去调用 Java 的方法
// 获取类,主要用于获取静态字段或调用静态方法,常用来获取 UnityPlayer AndroidJavaClass jc = new AndroidJavaClass("com.unity.game.UnityPlayerActivity"); // 获取静态字段,只有泛型版本 AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); // 调用对象方法:使用 AndroidJavaObject 类的 Call 调用Java方法。 jo.Call(javaFuncName, args);
Android 回调 Unity
Android 主动调用 Unity 可以通过 Sendmessage 方法
// objectName: Unity 对象的名称 // methodName: Unity 对象绑定的脚本方法名 // message: 自定义消息 UnityPlayer.UnitySendMessage(String objectName, String methodName, String message);
该方法有一个弊端,就是发送消息的方法对应的类,必须要挂载在一个 game object 上。
该方法有一点需要注意,就是在原生触发回调接口的时候,可能跟 Unity 的主线程并不是一个线程,此时需要通知 Unity 主线程执行回调。
Unity 调用 IOS OC方法
// DllImport这个方法相当于是告诉Unity,有一个CallObjCFunc函数在外部会实现。 // 使用这个方法必须要导入System.Runtime.InteropServices; [DllImport("__Internal")] private static extern void CallObjCFunc(string funcName); public static void CallNativeFunction(string funcName, params object[] args) { CallObjCFunc(funcName); }
对应的CallObjCFunc在oc层
extern "C" { void CallObjCFunc(const char* methodName) { SEL selector = NSSelectorFromString([NSString stringWithUTF8String:methodName]); if ([Plugin respondsToSelector:selector]) { [Plugin performSelector:selector]; } } }
IOS 回调 Unity
iOS 主动调用 Unity 可以通过 Sendmessage 方法
NSString *data = @"";//需要传递的参数 UnitySendMessage("Game", "CallFromNative", [data UTF8String]);
整合后的代码
SDKInterface.cs
1 using UnityEngine; 2 using System.Collections; 3 using LitJson; 4 5 #if UNITY_IOS && !UNITY_EDITOR 6 using System.Runtime.InteropServices; 7 #endif 8 9 public class SDKInterface : MonoBehaviour 10 { 11 private static SDKInterface m_instance; 12 public static SDKInterface Instance 13 { 14 get 15 { 16 if (m_instance == null) 17 { 18 if (Game.game) 19 { 20 m_instance = Game.game.gameObject.AddComponent<SDKInterface>(); 21 Debug.Log("SDKInterface initialized"); 22 } 23 } 24 return m_instance; 25 } 26 } 27 28 29 #if UNITY_ANDROID && !UNITY_EDITOR 30 private const string JAVA_CLASS_NAME = "com.unity.game.UnityPlayerActivity"; 31 private static void CallJavaFunc(string javaFuncName, params object[] args) 32 { 33 try 34 { 35 using (AndroidJavaClass jc = new AndroidJavaClass(JAVA_CLASS_NAME)) 36 { 37 //获取Activity 38 using (AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity")) 39 { 40 //调用Java方法 41 if (args == null) 42 { 43 jo.Call(javaFuncName); 44 } 45 else 46 { 47 jo.Call(javaFuncName, args); 48 } 49 } 50 } 51 } 52 catch (System.Exception ex) 53 { 54 Debug.LogError("callSdk error: " + ex.Message); 55 } 56 } 57 #endif 58 59 #if UNITY_IOS && !UNITY_EDITOR 60 // DllImport这个方法相当于是告诉Unity,有一个CallObjCFunc函数在外部会实现。 61 // 使用这个方法必须要导入System.Runtime.InteropServices; 62 [DllImport("__Internal")] 63 private static extern void CallObjCFunc(string funcName); 64 #endif 65 66 public static void CallNativeFunction(string funcName, params object[] args) 67 { 68 if (Instance == null) 69 { 70 return; 71 } 72 73 Debug.Log("call native function: " + funcName); 74 #if UNITY_EDITOR 75 #else 76 #if UNITY_ANDROID 77 CallJavaFunc(funcName, args); 78 #elif UNITY_IOS 79 CallObjCFunc(funcName); 80 #endif 81 #endif 82 } 83 84 //从java层或者oc层调用 85 public void CallFromNative(string data) 86 { 87 Debug.Log("call from native: " + data); 88 89 JsonData json = JsonMapper.ToObject(data); 90 string funcname = (string)json["FuncName"]; 91 92 Game.game.luaManager.CallFunction(funcname, data); 93 } 94 }
UnityPlayerActivity.cs
.. public class UnityPlayerActivity extends Activity { .. public void getStartupData() { String data = ""; UnityPlayer.UnitySendMessage("Game", "CallFromNative", data); } .. }
Plugin.m
1 #import "Plugin.h" 2 3 @implementation Plugin 4 5 +(void)getStartupData 6 { 7 NSString *data = @""; 8 9 UnitySendMessage("Game", "CallFromNative", [data UTF8String]); 10 } 11 12 @end 13 14 extern "C" { 15 void CallObjCFunc(const char* methodName) 16 { 17 SEL selector = NSSelectorFromString([NSString stringWithUTF8String:methodName]); 18 19 if ([Plugin respondsToSelector:selector]) { 20 [Plugin performSelector:selector]; 21 } 22 } 23 }