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的不同?
答案 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
}
。