- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在 Unity3d 引擎上开发适用于 Android 的应用程序。此应用程序必须通过网络套接字连接到我在 PC 上的服务器。我找到了一些适用于 Android 的 Unity3d 插件示例。基于它们,我在 C# 上为 Unity3d 和 Java 为 Android 编写了一些代码。我发现网络操作不能在 Android 应用程序的 UI 线程中运行。所以我必须使用 AsynTask 进行网络请求。我也尝试从 c# 脚本调用非静态方法,但它们不返回任何数据。只有静态调用从 Java 应用程序返回数据。所以我的 AsyncTask 类是静态的。但是,当我使用 AsyncTask 作业调用静态函数以通过网络获取数据时,我的应用程序崩溃了。我收到错误。你能帮我解决我的问题吗?我看到两种解决此问题的方法:1) 更改我的 Unity3d c# 代码以通过非静态方法调用获取数据。将 Java 代码中的所有方法更改为非静态。2) 更改我的 Java 代码以使用静态方法和静态 AsyncTask。
我的 C# 脚本 AndroidClientPlugin.cs:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
public class AndroidClientPlugin : MonoBehaviour {
private float TEST;
private AndroidJavaClass cls_UnityPlayer;
private AndroidJavaObject obj_Activity;
private AndroidJavaClass cls_CompassActivity;
// Use this for initialization
void Start () {
AndroidJNI.AttachCurrentThread();
cls_UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
obj_Activity = cls_UnityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
cls_CompassActivity = new AndroidJavaClass("com.lab.Android.AndroidClientPlugin");
cls_CompassActivity.SetStatic<String>("ServerAddressValue", "192.168.1.5");
cls_CompassActivity.SetStatic<String>("ServerPortValue", "8881");
}
void OnGUI() {
GUI.Label(new Rect(Screen.width / 2 -200, Screen.height / 2, 400,100), "x = " + TEST.ToString());
}
void Update()
{
if(cls_CompassActivity.CallStatic<bool>("GetData"))
{
TEST = cls_CompassActivity.CallStatic<float>("getPosX");
}
}
}
我的 Java 脚本 AndroidClientPlugin.java:
package com.lab.Android;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Looper;
import android.os.StrictMode;
import android.util.Log;
import android.content.Context;
import android.content.Intent;
import android.app.Activity;
public class AndroidClientPlugin extends UnityPlayerActivity {
//Server address parameters
public static String ServerAddressValue;
public static String ServerPortValue;
//Tracker parameters
public static String vServerName;
public static String vSensorNumber;
private static SensorData vTaskResult;
public static cTask BackgroundTask;
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
//set thread strict mode off
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
vTaskResult = new SensorData();
ServerAddressValue = "192.168.1.5";
ServerPortValue = "8881";
vServerName = "Tracker0";
vSensorNumber = "0";
BackgroundTask = new cTask();
}
@Override
protected void onResume()
{
super.onResume();
}
@Override
protected void onStop()
{
super.onStop();
}
public static boolean GetData()
{
cTaskResult taskResult = new cTaskResult();
taskResult = BackgroundTask.DoAsyncTask(ServerAddressValue, ServerPortValue, vServerName, vSensorNumber);
vTaskResult = taskResult.ResultData;
return taskResult.DataIsReady;
}
public static class cTaskResult
{
public boolean DataIsReady;
public SensorData ResultData;
public cTaskResult()
{
DataIsReady = false;
ResultData = new SensorData();
}
}
public static class cTask
{
public cTask()
{
}
public cTaskResult DoAsyncTask(String serverAddress, String serverPort, String trackerName, String trackerSensorNumber)
{
cTaskResult Result = new cTaskResult();
GetDataTask Task;
Task = new GetDataTask();
Task.execute(serverAddress, serverPort, trackerName, trackerSensorNumber, Result);
try {
Result = Task.get(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return Result;
}
public static class GetDataTask extends AsyncTask<Object, Void, cTaskResult>
{
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected cTaskResult doInBackground(Object... params) {
cTaskResult TMPData = new cTaskResult();
//doing network requests
//TMPData.DataIsReady = NetClient.getInstance().GetData((String)params[0], (String)params[1], (String)params[2], Integer.valueOf((String)params[3]), TMPData.ResultData);
//TMPData is a result of network operations
TMPData.DataIsReady = true;
TMPData.ResultData = new SensorData();
return TMPData;
}
@Override
protected void onPostExecute(cTaskResult result) {
super.onPostExecute(result);
}
}
}
public static float getPosX()
{
return vTaskResult.posX;
}
}
调试信息:
09-11 12:56:05.514: E/CMarlinMediator(137): Error : MarlinMediator Failed to get TrustedTime
09-11 12:56:05.594: E/CMarlinMediator(137): Error : MarlinMediator Failed to get TrustedTime
09-11 12:56:12.184: E/Adreno200-EGL(7590): <qeglDrvAPI_eglGetConfigAttrib:484>: EGL_BAD_ATTRIBUTE
09-11 12:56:12.184: E/Adreno200-EGL(7590): <qeglDrvAPI_eglGetConfigAttrib:484>: EGL_BAD_ATTRIBUTE
09-11 12:56:12.184: E/Adreno200-EGL(7590): <qeglDrvAPI_eglGetConfigAttrib:484>: EGL_BAD_ATTRIBUTE
09-11 12:56:14.304: E/AndroidRuntime(7590): FATAL EXCEPTION: GLThread 741
09-11 12:56:14.304: E/AndroidRuntime(7590): java.lang.ExceptionInInitializerError
09-11 12:56:14.304: E/AndroidRuntime(7590): at com.lab.Android.AndroidClientPlugin$cTask.DoAsyncTask(AndroidClientPlugin.java:128)
09-11 12:56:14.304: E/AndroidRuntime(7590): at com.lab.Android.AndroidClientPlugin.GetData(AndroidClientPlugin.java:79)
09-11 12:56:14.304: E/AndroidRuntime(7590): at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
09-11 12:56:14.304: E/AndroidRuntime(7590): at com.unity3d.player.UnityPlayer.onDrawFrame(Unknown Source)
09-11 12:56:14.304: E/AndroidRuntime(7590): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1462)
09-11 12:56:14.304: E/AndroidRuntime(7590): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1216)
09-11 12:56:14.304: E/AndroidRuntime(7590): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
09-11 12:56:14.304: E/AndroidRuntime(7590): at android.os.Handler.<init>(Handler.java:121)
09-11 12:56:14.304: E/AndroidRuntime(7590): at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:607)
09-11 12:56:14.304: E/AndroidRuntime(7590): at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:607)
09-11 12:56:14.304: E/AndroidRuntime(7590): at android.os.AsyncTask.<clinit>(AsyncTask.java:190)
09-11 12:56:14.304: E/AndroidRuntime(7590): ... 6 more
09-11 12:56:15.194: E/CMarlinMediator(137): Error : MarlinMediator Failed to get TrustedTime
09-11 12:56:15.234: E/CMarlinMediator(137): Error : MarlinMediator Failed to get TrustedTime
最佳答案
首先,为什么在Update函数中调用android代码?因为它会在每一帧被调用。
也许你应该放置一些标志来指示 native 代码正在运行,并且不要调用它两次。
关于您的问题,据我所知,必须在 UI-Thread 中调用 AsyncTask 创建和任务运行。问题是:
Update
方法中调用静态方法 AndroidClientPlugin.GetData
。据我所知,这与android的UI-Thread不是同一个线程。因此,您在 Unity 自己的线程中调用了它,并且:我的解决办法是(你可以试试):
public static void GetData()
{
//this will be called on UIThread of Android
com.unity3d.player.UnityPlayer.currentActivity.runOnUiThread(new Runnable(){
public void run(){
cTaskResult taskResult = new cTaskResult();
taskResult = BackgroundTask.DoAsyncTask(ServerAddressValue, ServerPortValue, vServerName, vSensorNumber);
vTaskResult = taskResult.ResultData;
com.unity3d.player.UnityPlayer.currentActivity.SendMessage("YourGameObjectName", "YourMethodName", taskResult.DataIsReady);
//return taskResult.DataIsReady;
}
});
}
关于c# - Unity3d Android 插件静态 AsyncTask 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12367438/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!