G_B*_*G_B 3 c# unity-game-engine
我正在为 Unity3D 游戏创建简单的 Android 插件来显示吐司和本机弹出窗口。当我想从 Java 类调用方法时,我使用 AndroidJavaClass 和 AndroidJavaObject,就像在 Unity 文档中一样:
AndroidJavaObject bridge = new AndroidJavaObject(CLASS_NAME);
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject act = jc.GetStatic<AndroidJavaObject>("currentActivity");
act.Call("runOnUiThread", new AndroidJavaRunnable(() =>
{
bridge.CallStatic(methodName, args);
}));
Run Code Online (Sandbox Code Playgroud)
Unity 文档(https://docs.unity3d.com/Manual/AndroidJARPlugins.html “在 Unity 中使用 Java 插件时的最佳实践”)建议使用 using 语句,例如
using (AndroidJavaClass cls = new AndroidJavaClass("java.util.Locale")) {
using(AndroidJavaObject locale = cls.CallStatic<AndroidJavaObject>("getDefault")) {
Debug.Log("current lang = " + locale.Call<string>("getDisplayLanguage"));
}
}
Run Code Online (Sandbox Code Playgroud)
但表示这是“计算成本高的方法”。
问题:我是否应该缓存 AndroidJavaClass 和 AndroidJavaObject 的实例?
感谢您的回答
这取决于使用情况。
如果您需要调用方法一次或只是几次,然后用using语句,以便AndroidJavaClass和AndroidJavaObject 将尽快销毁和释放内存。
如果你调用这个方法每帧或大部分时间,你应该不使用using的语句。这将创建一个新的实例AndroidJavaClass,并AndroidJavaObject在每次使用它的时候using再声明摧毁它。它会导致垃圾收集器更频繁地发生,并且 GC 运行会导致您的游戏出现打嗝或暂时冻结,尤其是在移动设备上(在这种情况下为 Android)。
例如,如果您的问题中的第一个代码示例需要在每一帧中调用,那么将它们缓存在Start函数中并在函数中使用它们Update。当场景重新加载或另一个新场景加载时,它会清理:
AndroidJavaObject bridge;
AndroidJavaClass jc;
AndroidJavaObject act;
//Cache
void Start()
{
bridge = new AndroidJavaObject(CLASS_NAME);
jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
act = jc.GetStatic<AndroidJavaObject>("currentActivity");
}
void Update()
{
DoSomething();
}
void DoSomething()
{
act.Call("runOnUiThread", new AndroidJavaRunnable(() =>
{
bridge.CallStatic(methodName, args);
}));
}
Run Code Online (Sandbox Code Playgroud)