Каковы конкретные условия, которые заставляют Unity3D AndroidJavaClass бросать новые?

Этот код генерирует новый AndroidJavaClass:

public static bool Initialize(ref string msg)
 {
 if (instance_ == null)
 {
 GameObject newGameObject = new GameObject("EstimoteDeviceController");
 newGameObject.AddComponent<estimotedeviceplugin>();
 instance_ = newGameObject.GetComponent<estimotedeviceplugin>();

 #if UNITY_ANDROID
 try
 {
 using (AndroidJavaClass androidClass = new AndroidJavaClass("EstimoteBeaconActivity"))
 {
 instance_.androidActivity_ = androidClass.GetStatic<androidjavaobject>("mContext");
 }
 }
 catch (Exception e)
 {
 msg = e.StackTrace;
 Debug.LogWarning("[EstimoteDevicePlugin] - Initialize(): exception thrown: " + msg);
 return false;
 }
 #endif

 }

 return true;
 }
</androidjavaobject></estimotedeviceplugin></estimotedeviceplugin>

Создает эту трассировку стека, когда она бросает:

at ***********.AndroidJNISafe.CheckException () [0x00000] in <filename unknown="">:0
at ***********.AndroidJNISafe.CallStaticObjectMethod (IntPtr clazz.IntPtr methodID, ***********.jvalue[] args) [0x00000] in <filename unknown="">:0
at ***********.AndroidJavaObject._CallStatic[AndroidJavaObject] (System.String.methodName.System.Object[] args) [0x00000] in <filename unknown="">:0
at ***********.AndroidJavaObject.CallStatic[AndroidJavaObject] (System.String.methodName.System.Object[] args) [0x00000] in <filename unknown="">:0
at ***********.AndroidJavaObject.FindClass (System.String name) [0x00000] in <filename unknown="">:0 
at ***********.AndroidJavaObject._AndroidJavaClass (System.String className) [0x00000] in <filename unknown="">:0 
at ***********.AndroidJavaObject.AndroidJavaClass (System.String className) [0x00000] in <filename unknown="">:0 
at EstimoteDevice.EstimoteDevicePlugin.Initialize (System.String& msg) [0x00000] in <filename unknown="">:0 
</filename></filename></filename></filename></filename></filename></filename></filename>

Я искал это и до сих пор не нашел убедительного ответа на вопрос, почему это происходит, только то, что он делает, и поставщик подключаемых модулей (например, Facebook) обратился к нему в более поздней версии своего плагина.

Я повторил это с помощью инструментов Android SDK 23, платформы Android + сборки 19 + 20, SDK v4.4.2 + v4.4W, как на Windows8.1, так и на MacOSX 10.9.4. Это Unity v4.6b17.

Я предполагаю, что это проблема сборки с моим.jar файлом, поскольку Unity, по-видимому, не может найти класс, на который я ссылаюсь на строку в вызове. У меня есть опыт написания плагинов Unity для iOS.

Заранее спасибо.

2 ответа

Это больше не бросает:

public static bool Initialize(ref string zMsg)
 {
 if (instance_ == null)
 {
 GameObject newGameObject = new GameObject("EstimoteDeviceController");
 newGameObject.AddComponent<estimotedeviceplugin>();
 instance_ = newGameObject.GetComponent<estimotedeviceplugin>();

 #if UNITY_ANDROID
 try
 {
 instance_.androidActivity_ = new AndroidJavaClass("com.colabproductions.UCC.EstimoteBeaconActivity");
 }
 catch (Exception e)
 {
 zMsg = e.StackTrace;
 Debug.LogWarning("[EstimoteDevicePlugin] - Initialize(): exception thrown: " + zMsg);
 return false;
 }
 #endif

 }

 return true;
 }
</estimotedeviceplugin></estimotedeviceplugin>

Копаясь в лоскутной одежде документации, связанной с этой темой, мне пришло в голову попытаться инициализировать мой java.lang.Class с помощью AndroidJavaClass и посмотреть, вернулась ли я к действительной ссылке на объект С#, который был вызван. Из приведенного выше кода вы можете вызвать статические методы/члены, но конструктор еще не вызывается, поэтому методы/члены экземпляра не доступны. Это говорит мне, что активность не была "автоматически построена", как описано в документах разработчика Android. К сожалению, конструктор является закрытым, поэтому я не могу его назвать.


Я подозреваю, что это связано с этой строкой:

using (AndroidJavaClass androidClass = new AndroidJavaClass("EstimoteBeaconActivity"))

Строка, которую вы вводите, должна быть строкой, включая пространство имён. Поэтому в проекте eclipse вы можете обнаружить, что класс принадлежит определенному пакету, например:

com.companyname.projectname.classname.

Вам нужно будет использовать тот же каталог в своем объявлении вашего класса java для Android.

AndroidJavaClass jc = new AndroidJavaClass("com.companyname.projectname.classname");

Если это действие, вам также необходимо убедиться, что он указан в вашем AndroidManifest.xml.

licensed under cc by-sa 3.0 with attribution.