Unity3D& Android:“UnityMain”和“主要”线程之间的区别?

时间:2015-08-11 23:54:49

标签: android multithreading unity3d

TLDR:我正在使用JNI从Unity C#调用我的自定义JAR。但是android库说它在“UnityMain”线程上运行,而活动的实际ui线程称为“main”。这两者有什么区别?

详细信息: 这对我来说是一个问题,因为我收到错误“无法在未调用Looper.prepare()的线程内创建处理程序”。这是从Java打印两个线程时得到的输出:

/// Java Output
Current Thread:    Thread[UnityMain,5,main]
MainLooper Thread: Thread[main,5,main]

要解决此问题,我正在使用Activity.runOnUiThread方法运行JNI调用:

/// Unity C# Code
activityObj.Call("runOnUiThread", new AndroidJavaRunnable(() => {
  // JNI calls and other stuff
}

现在,从Java打印两个线程时,我得到以下输出:

/// Java Output
Current Thread:    Thread[main,5,main]
MainLooper Thread: Thread[main,5,main]

现在唯一的问题是我无法从“主”线程(即“runOnUiThread”回调内部)进行Unity Coroutine或Invoke调用。我收到以下Unity错误:

/// Unity C# Output
E/Unity   (21048): Invoke can only be called from the main thread.
E/Unity   (21048): Constructors and field initializers will be executed from the loading thread when loading a scene.
E/Unity   (21048): Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.

那么“UnityMain”和“主要”线程之间有什么区别?为什么Java“主”线程与Unity的不同?

1 个答案:

答案 0 :(得分:4)

Unity运行自己的线程来处理它的处理。启动应用程序时,它不会篡夺Android操作系统创建的Android主线程。通常,当您编写传统的Android应用程序时,只有一个主线程,并且处理UI的所有内容都必须在主线程上运行。要使用第二个“主”线程,Unity是一个设计选择,可能是因为它可以做任何想做的事情而不会搞乱应用Android主线程。如果你想在Unity之外的Android UI中做任何事情,你需要让你的代码在主线程上运行。您可以使用以下代码段从任何地方执行此操作:

var array;

function test(id) {
    $.post( "main/updater.php", { id:id } ).done(function( data ) {
          array = JSON.stringify(data);
    });
}

如果您要调用的Android / Java代码可以访问Application上下文或Activity上下文,那么您也可以使用// return the first IPv4, non-dynamic/link-local, non-loopback address public static IPAddress GetIPAddress() { IPAddress[] hostAddresses = Dns.GetHostAddresses(""); foreach (IPAddress hostAddress in hostAddresses) { if (hostAddress.AddressFamily == AddressFamily.InterNetwork && !IPAddress.IsLoopback(hostAddress) && // ignore loopback addresses !hostAddress.ToString().StartsWith("169.254.")) // ignore link-local addresses return hostAddress; } return null; // or IPAddress.None if you prefer }