Michael A
Michael A

Reputation: 5840

JNI ERROR (app bug): accessed stale global reference

I am trying to embedd unity android plugin and face an issue

this is the code:

public class Veedi : MonoBehaviour {

private static AndroidJavaObject VeediObject= null;
private static AndroidJavaObject activityContext = null;
public int DeveloperID;
public int gameID;
void Start() {
    print("**********START__________");
    if(VeediObject == null) {
        print("**********VeediObject________");

        using(AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
        {
            print("**********AndroidJavaClass_________");
            activityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");
        }
        print("*******Before Init________");
        using(AndroidJavaClass pluginClass = new AndroidJavaClass("com.play.im.MainActivity")) {
            if(pluginClass != null) {

                activityContext.Call("runOnUiThread", new AndroidJavaRunnable(() => 
                {
                    print("0");
                    int attach = AndroidJNI.AttachCurrentThread();
                print("1");


                    VeediObject = pluginClass.CallStatic<AndroidJavaObject>("instance");
                print("2");
                    VeediObject.Call("setContext", activityContext);
                print("3");
                    VeediObject.Call("initVeedi",gameID,DeveloperID);
                    print("**********after Init__________");

                }));



            }
        }
    }
}

When the code reach the line:

VeediObject = pluginClass.CallStatic("instance");

It crahes in with a:

JNI ERROR (app bug): accessed stale global reference

Someone suggested to use:

AndroidJNI.NewGlobalRef

Can someone help with a direction to this problem? someone suggested its because the JNI refrence to the java objects changes

Upvotes: 0

Views: 2888

Answers (1)

Radu Diță
Radu Diță

Reputation: 14171

The C# reference to pluginClass is lost as soon as the enclosing block is finished.

You are calling Java code on the Android UI thread which means that the lambda function you're passing as the 2nd argument in AndroidJavaClass.Call is executed at a later time after the block holding the reference for pluginClass is lost and hence your error.

You should keep a reference to com.play.im.MainActivity outside of the using block. You can keep a reference to it as a member of the MonoBehaviour.

private static AndroidJavaClass pluginClass;

void Start()
{
  ...
  pluginClass = new AndroidJavaClass("com.play.im.MainActivity");

  if(pluginClass != null) {

            activityContext.Call("runOnUiThread", new AndroidJavaRunnable(() => 
            {
                print("0");
                int attach = AndroidJNI.AttachCurrentThread();
            print("1");


                VeediObject = pluginClass.CallStatic<AndroidJavaObject>("instance");
            print("2");
                VeediObject.Call("setContext", activityContext);
            print("3");
                VeediObject.Call("initVeedi",gameID,DeveloperID);
                print("**********after Init__________");

            }));



        }
}

Upvotes: 1

Related Questions