Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

AndroidJavaProxy pass empty string after using il2cpp

Discussion in 'Android' started by AnyLight, Apr 17, 2018.

  1. AnyLight

    AnyLight

    Joined:
    Jan 9, 2015
    Posts:
    1
    Hi everyone,

    I using AndroidJavaProxy to pass string result from java native WebRequest (Volley) into Unity project, it's all work before i using il2cpp to build Android Studio project.

    I found when using Android 5 (including below version) devices, if the length of response text from WebRequest was too long, then it become empty string in Unity side. I already added preserveAttribute to my class and method, but the issue still there.

    I print the response text in java side, it was all correct, but when i print the text from callback method in unity, it was empty.

    Other Android Version (5 above) not happen this issue, change to mono scripting backend also work fine.

    Unity version : 2017.4.1f1
    Volley version : 1.1.0
    Scripting Backend : il2cpp

    Did someone saw this issue before? I can't found any discuss on internet.

    Thanks for your help!
     
  2. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,773
    Can you provide details about the C# code used for marshaling this string? I suspect there is some problem related to p/invoke here, but we will need to see the code to be sure.
     
  3. fourdesire

    fourdesire

    Joined:
    Sep 26, 2014
    Posts:
    17
    Hi @JoshPeterson, We had the similar issue with il2cpp and we finally figure it out that:

    The Unity will receive empty string when passing the string that contains emoji chars.

    We have a java class declared:

    Code (JavaScript):
    1. public interface NativeRequestListener {
    2.  
    3.     void onRequestCompleted (int statusCode, String errorMsg, String jsonResponse);
    4. }
    and in Unity

    Code (CSharp):
    1. public class FDNativeRequestListenerCallBack : AndroidJavaProxy {
    2.  
    3.         FDNativeRequest m_Request;
    4.  
    5.         public FDNativeRequestListenerCallBack (FDNativeRequest request) : base ("com.fourdesire.unity.FDNativeRequestListener") {
    6.  
    7.             m_Request = request;
    8.         }
    9.  
    10.         public void onRequestCompleted (int statusCode, string errorMsg, string jsonResponse) {
    11.  
    12.             We'll get empty string if jsonResponse contains emoji chars ******** with Android 5 and below
    13.        }
    14.    }
    15.  
    We pass the m_Listener:FDNativeRequestListenerCallBack to java as follows:

    Code (CSharp):
    1. AndroidJavaClass unityHelper = new AndroidJavaClass ("com.fourdesire.unity.FDNativeRequestHelper");
    2.             unityHelper.CallStatic ("Get", uri.AbsoluteUri, JsonConvert.SerializeObject (m_Parameters), m_Listener);
    So, in order to fix the issue temporarily, we pass bytearray instead of string as follows:

    Code (JavaScript):
    1. public interface FDNativeRequestListener {
    2.  
    3.     void onRequestCompletedBytes (int statusCode, String errorMsg, FDNativeRequest.ByteArrayWrapper jsonResponse);
    4. }
    5.  
    6. public class FDNativeRequest {
    7.  
    8.     public class ByteArrayWrapper {
    9.  
    10.         public byte[] Buffer;
    11.  
    12.         public ByteArrayWrapper (byte[] buffer) {
    13.  
    14.             Buffer=buffer;
    15.         }
    16.     }
    17.  
    18.      ......
    19. }
    in Unity

    Code (CSharp):
    1. public class FDNativeRequestListenerCallBack : AndroidJavaProxy {
    2.  
    3.         public FDNativeRequestListenerCallBack () : base ("com.fourdesire.unity.FDNativeRequestListener") {
    4.  
    5.         }
    6.  
    7.         public void onRequestCompletedBytes (int statusCode, string errorMsg, AndroidJavaObject data) {
    8.  
    9.             AndroidJavaObject bufferObject = data.Get<AndroidJavaObject> ("Buffer");
    10.             byte [] buffer = AndroidJNIHelper.ConvertFromJNIArray<byte []> (bufferObject.GetRawObject ());
    11.  
    12.             var jsonString = System.Text.Encoding.UTF8.GetString (buffer);
    13.         }
    14.     }
    Now the problem resolved for most of android 5 users, however we got another issue reported from Fabric (but not that much).

    Caused by java.lang.AbstractMethodError
    abstract method "void com.fourdesire.unity.FDNativeRequestListener.onRequestCompletedBytes(int, java.lang.String, com.fourdesire.unity.FDNativeRequest$ByteArrayWrapper)"

    we are using Unity 2017.4.1f1
     
  4. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,773
    I'm glad you were able to find a work around. I'm unsure why this won't work with certain characters.

    Are there any more details about the new error? I don't know what java.lang.AbstractMethodError means.