Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unity3d development: JNI ERROR (app bug): accessed stale local reference 0x200001 (index 0 in a table of size 0)

I use AndroidJavaObject when I develop unity3d project. And I try on a very simple code as follows, but it throws an exception as in the title.

using UnityEngine;
using System.Collections;
using System.Threading;

public class MainScript : MonoBehaviour {

    // Use this for initialization
    void Start () {
	}

    void OnGUI()
    {
        if (GUI.Button(new Rect(50, 50, 1000, 200), "Open Activity"))
        {
            Debug.Log("pressed");

            Thread t1 = new Thread(new ThreadStart(ListenThread));
            t1.IsBackground = false;
            t1.Start();
        }

        //quit  
        if (Input.GetKey(KeyCode.Escape) || Input.GetKey(KeyCode.Home))
        {
            Application.Quit();
        }
    }


    public static void ListenThread()
    {
        AndroidJavaObject jo = new AndroidJavaObject("java.lang.String", "some_string");
        int hash = jo.Call<int>("hashCode");
        Debug.Log(hash);
    }


}

However, if I don't put the AndroidJavaObject in a thread as follows, it will run normally.

using UnityEngine;
using System.Collections;
using System.Threading;

public class MainScript : MonoBehaviour {

    // Use this for initialization
    void Start () {
	}

    void OnGUI()
    {
        if (GUI.Button(new Rect(50, 50, 1000, 200), "Open Activity"))
        {
            Debug.Log("pressed");

            AndroidJavaObject jo = new AndroidJavaObject("java.lang.String", "some_string");
            int hash = jo.Call<int>("hashCode");
            Debug.Log(hash);
        }

        //quit  
        if (Input.GetKey(KeyCode.Escape) || Input.GetKey(KeyCode.Home))
        {
            Application.Quit();
        }
    }


    public static void ListenThread()
    {
        AndroidJavaObject jo = new AndroidJavaObject("java.lang.String", "some_string");
        int hash = jo.Call<int>("hashCode");
        Debug.Log(hash);
    }


}

But in my application, a blocked function of the AndroidJavaObject will be called, so I have to use a thread. What's the problem in the first code? Is it because that unity3d doesnot support AndroidJavaObject in the thread? Please help, thanks!!

like image 831
Niubility Avatar asked Sep 30 '16 06:09

Niubility


1 Answers

Haha, I've solved it. Just attach the thread to AndroidJNI, for the thread needs to be attached to a JVM. The code is as follows:

public static void ListenThread()
{
  AndroidJNI.AttachCurrentThread();
  AndroidJavaObject jo = new AndroidJavaObject("java.lang.String", "some_string");
  int hash = jo.Call<int>("hashCode");
  Debug.Log(hash);
  AndroidJNI.DetachCurrentThread();
}

Donot forget to detach when the thread is going to be finished.

like image 73
Niubility Avatar answered Oct 13 '22 03:10

Niubility