Unity3d motoru üzerinde android için bir uygulama geliştiriyorum. Bu uygulama sunucuya PC'mdeki ağ soketleri üzerinden bağlanmalıdır. Android için bazı Unity3d eklenti örnekleri buldum. Onlara dayanarak Unity3d için C# ve Android için Java'da bir kod yazdım. Android uygulamasında ağ işlemlerinin UI-thread'da çalıştırılmaması gerektiğini öğrendim. Bu yüzden ağ istekleri için AsynTask kullanmalıyım. Ayrıca C# komut dosyasından statik olmayan yöntemleri çağırmayı denedim, ancak hiçbir veri göndermiyorlar. Sadece statik çağrılar, java uygulamasından veri döndürür. Yani AsyncTask sınıfım statik. Ancak ağ üzerinden veri almak için AsyncTask iş ile statik işlevini çağırdığınızda, benim uygulama çöktü. Hataları alıyorum. Sorunlarımı düzeltmeme yardım eder misin? Bu sorunu gidermek için iki yol görüyorum: 1) Statik olmayan yöntem çağrıları yoluyla veri almak için Unity3d için C# kodumu değiştirin. Java kodunda tüm yöntemleri Non-Static olarak değiştirin. 2) Statik yöntemler ve statik AsyncTask ile çalışmak için Java kodumu değiştir.Unity3d Android eklentisi AsyncTask
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");
}
}
}
Benim Java komut 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;
}
}
ayıklama iletileri:
Benim C# komut AndroidClientPlugin.cs
tüm09-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