- Home /
Unable to retrieve return values from android library (aar file) to c# in unity 5.3.4p3 (string,int,bool) using AndroidJavaClass.Call()
Hello I'm trying it include an android library in my unity project. My android code is as follows:
package com.androidtester;
public class ATests {
public String teststr() {
return "testing...";
}
public boolean testbool() {
return true;
}
public int testint() {
return 123;
}
}
My c# code is as follows:
public class GameControl : MonoBehaviour {
void Start ()
{
try {
AndroidJavaClass atests = new AndroidJavaClass ("com.androidtester.ATests");
Debug.Log ("Test Str:" + atests.Call<string> ("teststr"));
Debug.Log ("Test Int:" + atests.Call<int> ("testint"));
Debug.Log ("Test Bool:" + atests.Call<bool> ("testbool"));
} catch (Exception e) {
Debug.Log ("ATests Error..." + e.ToString ());
}
}
}
This is within a blank unity 2D project with an empty game object containing GameControl. My folder structure is as so:
When I run my unity application on an android device I see this in adb's logcat:
I/Unity (29910): GameControl:Start() (at ./Assets/GameControl.cs:10)
I/Unity (29910):
I/Unity (29910): (Filename: ./Assets/GameControl.cs Line: 10)
I/Unity (29910):
I/Unity (29910): Test Str:
I/Unity (29910): UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
I/Unity (29910): UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
I/Unity (29910): UnityEngine.Logger:Log(LogType, Object)
I/Unity (29910): UnityEngine.Debug:Log(Object)
I/Unity (29910): GameControl:Start() (at ./Assets/GameControl.cs:13)
I/Unity (29910):
I/Unity (29910): (Filename: ./Assets/GameControl.cs Line: 13)
I/Unity (29910):
I/Unity (29910): Test Int:0
I/Unity (29910): UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
I/Unity (29910): UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
I/Unity (29910): UnityEngine.Logger:Log(LogType, Object)
I/Unity (29910): UnityEngine.Debug:Log(Object)
I/Unity (29910): GameControl:Start() (at ./Assets/GameControl.cs:14)
I/Unity (29910):
I/Unity (29910): (Filename: ./Assets/GameControl.cs Line: 14)
I/Unity (29910):
I/Unity (29910): Test Bool:False
I/Unity (29910): UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
I/Unity (29910): UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
I/Unity (29910): UnityEngine.Logger:Log(LogType, Object)
I/Unity (29910): UnityEngine.Debug:Log(Object)
I/Unity (29910): GameControl:Start() (at ./Assets/GameControl.cs:15)
I/Unity (29910):
I/Unity (29910): (Filename: ./Assets/GameControl.cs Line: 15)
I/Unity (29910):
For some reason the return values from android are all wrong. If I enter a different function name or return type they generate exceptions so I know the signatures are matching up. I should mention that if I switch the android function to 'public static' then use 'AndroidJavaClass.CallStatic() in c# everything works fine. It's the plain AndroidJavaClass.Call() that gives incorrect return values.
I should mention that using this approach does work:
Debug.Log ("Test Str:" + atests.CallStatic<string> ("teststr"));
Debug.Log ("Test Int:" + atests.CallStatic<int> ("testint"));
Debug.Log ("Test Bool:" + atests.CallStatic<bool> ("testbool"));
when I change the android functions to static functions:
public static String teststr() {
return "testing...";
}
public static boolean testbool() {
return true;
}
public static int testint() {
return 123;
}
but it does not work when they are not static & I use the atests.Call() method. What I need is for the Call() approach to work properly without static function usage.
Answer by meat5000 · May 10, 2016 at 09:08 PM
In my last plugin I had to Create an instance inside the plugin class.
After my AndroidJavaClass call I used my handle to call the AndroidJavaObject 'instance'. I use this instance handle, then, to retrieve members.
This is probably why static works. Non-static requires an instance I do believe.
The other thing is that Unity expects a .JAR file. I'm not sure it'll handle .AAR
AAR plugin support has been added in 5.0b19. Feel free to try latest beta, your feedback is welcome. Just drop an .aar file into any folder of Unity project, it should be detected as Android-only plugin, and enjoy
posted by unity technologies on jan 16th, 2015 http://forum.unity3d.com/threads/does-unity-support-using-aar-package-as-android-plugin-library.272776/
the aar file seems to be ok it expands into a .jar during compilation I noticed. The problem seems to be directly related to context / instance life span for sure.
I've read the manual at http://docs.unity3d.com/$$anonymous$$anual/PluginsForAndroid.html but I don't see anything that describes exactly what you're referring to. Looking at their string example:
AndroidJavaObject jo = new AndroidJavaObject("java.lang.String", "some_string");
int hash = jo.Call<int>("hashCode");
its using the same approach I'm currently using for my ATests class.
Can you elaborate on the approach you took to create an instance inside your plugin class? That sounds like something worth exploring.
Do you mean doing this:
Java Code:
public class PluginWrapper {
public static ATests myStaticTests; //instance reference?
public PluginWrapper() {
if(!PluginWrapper.myStaticTests) {
PluginWrapper.myStaticTests = new ATests();
}
}
}
c# code:
AndroidJavaObject wrapper = new AndroidJavaClass ("com.androidtester.PluginWrapper");
AndroidJavaObject innerInstance = wrapper.Get ("myStaticTests");
innerInstance.Call ("teststr");
or am I missing what you're suggestingL
@meat5000 Oops I responded to your answer as a second comment above & it doesn't look like I can move it. Can you review & let me know your thoughts?
Check out my last plugin
http://answers.unity3d.com/questions/1163907/how-can-i-detect-if-the-back-button-is-virtual-or.html
Follow the class/instance pattern and respective class/object calls on the unity side. On mobile atm, ill follow up tomorrow. Btw you dont need the context part.
@meat5000 you were right thanks for the nudge in the right direction.
Ins$$anonymous$$d of this for non-static methods:
AndroidJavaClass myAndroidPlugin = new AndroidJavaClass("com.myplugin");
myAndroidPlugin.Call("..."); //does not work on AndroidJavaClass...only on AndroidJavaObject
do this (in c#):
AndroidJavaClass myAndroidClass = new AndroidJavaClass("com.myplugin");
AndroidJavaObject myAndroidPlugin = myAndroidClass.CallStatic<AndroidJavaObject>("instance");
myAndroidPlugin.Call("...");
and this (in java):
public class $$anonymous$$yAndroidPlugin {
private static $$anonymous$$yAndroidPlugin m_instance;
public $$anonymous$$yAndroidPlugin() {
m_instance = this;
}
public static $$anonymous$$yAndroidPlugin instance() {
if (m_instance == null) {
m_instance = new $$anonymous$$yAndroidPlugin();
}
return m_instance;
}
}
$$anonymous$$ost welcome. Click accept to mark the answer correct :)
Your answer
Follow this Question
Related Questions
Get Phone number of android mobile device - Android native code to Unity c# 3 Answers
Using CustomUnityPlayerActivity, which inherits from UnityPlayerActivity, will cause problems. 0 Answers
java.lang.ClassNotFoundException while running Android activity 2 Answers