Unity和Android、iOS原生交互

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 }

 

posted @ 2021-11-27 18:15  Ring_1992  阅读(731)  评论(0编辑  收藏  举报