Cannot create androidjavaobject.

I’d like to do a test about how Unity called the android classes.
that’s my code in Eclipse.

package com.mars.plugins;
import android.os.Bundle;
import android.util.Log;
import com.unity3d.player.UnityPlayerActivity;

public class Test extends UnityPlayerActivity
{
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		Log.d("MarsPlugin", "onCreate call!!");
	}
}

And the AndroidManifest.xml in Unity

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.unity3d.player"
	android:installLocation="preferExternal"
	android:theme="@android:style/Theme.NoTitleBar"
    android:versionCode="1"
    android:versionName="1.0">
    <supports-screens
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true"
        android:anyDensity="true"/>

    <application
		android:icon="@drawable/app_icon"
        android:label="@string/app_name"
        android:debuggable="true">
        <activity android:name="com.unity3d.player.UnityPlayerNativeActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
            <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />
        </activity>
        
      	<activity android:name="com.mars.plugins.Test" 
        android:configChanges="keyboardHidden|orientation|screenSize|smallestScreenSize" />
        
        <!--
        <activity android:name="com.mars.plugins.Test" 
        android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
    	</activity>       
    	-->
        
    </application>
</manifest>

The script called the plugin in Unity

using UnityEngine;
using System.Collections;

public class TheTest : MonoBehaviour
{

    // Use this for initialization
    void Start()
    {
    
        Debug.Log("On Create JavaClass");
        using (AndroidJavaClass jc = new AndroidJavaClass("com.mars.plugins.Test"))
        {
            if(jc==null)
            {
                Debug.Log("jc is null");
                return;
            }
        }

        Debug.Log("On Create JavaObject");
        using (AndroidJavaObject jo = new AndroidJavaObject("com.mars.plugins.Test"))
        {
            if(jo==null)
            {
                Debug.Log("jo is null");
                return;
            }
        }

    }

}

While I do the test, I saw the error from ADT Logcat

09-20 11:33:07.110: I/Unity(4906): On Create JavaClass
09-20 11:33:07.110: I/Unity(4906):  
09-20 11:33:07.110: I/Unity(4906): (Filename: ./artifacts/AndroidManagedGenerated/UnityEngineDebug.cpp Line: 49)
09-20 11:33:07.170: I/Unity(4906): On Create JavaObject
09-20 11:33:07.170: I/Unity(4906):  
09-20 11:33:07.170: I/Unity(4906): (Filename: ./artifacts/AndroidManagedGenerated/UnityEngineDebug.cpp Line: 49)
09-20 11:33:07.450: I/Unity(4906): AndroidJavaException: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
09-20 11:33:07.450: I/Unity(4906):   at UnityEngine.AndroidJNISafe.CheckException () [0x00000] in <filename unknown>:0 
09-20 11:33:07.450: I/Unity(4906):   at UnityEngine.AndroidJNISafe.NewObject (IntPtr clazz, IntPtr methodID, UnityEngine.jvalue[] args) [0x00000] in <filename unknown>:0 
09-20 11:33:07.450: I/Unity(4906):   at UnityEngine.AndroidJavaObject._AndroidJavaObject (System.String className, System.Object[] args) [0x00000] in <filename unknown>:0 
09-20 11:33:07.450: I/Unity(4906):   at UnityEngine.AndroidJavaObject..ctor (System.String className, System.Object[] args) [0x00000] in <filename unknown>:0 
09-20 11:33:07.450: I/Unity(4906):   at TheTest.Start () [0x00000] in <filename unknown>:0 
09-20 11:33:07.450: I/Unity(4906):  
09-20 11:33:07.450: I/Unity(4906): (Filename:  Line: -1)

I don’t know where’s wrong, could some one give me a help ?

It looks like an exception is being thrown from within your java code. The clue is in the error message:

Can't create handler inside thread that has not called Looper.prepare()

seems to me that you’re trying to do some UI work outside of the UI thread. Here’s a handy little routine that can push code to the UI thread from pretty much anywhere in Android, so long as you have reference to a context (denoted as “_c” in this code):

Handler h = new Handler(_c.getMainLooper());
		h.post(new Runnable(){

			@Override
			public void run()
			{
				Toast.makeText(_c, "I'm running on the UI Thread", Toast.LENGTH_LONG).show();					
			}}
		);

There are a few issues with the code/manifest you provided:

  1. In the manifest, you should declare your main (LAUNCHER) activity as the custom activity you created:

    <?xml version="1.0" encoding="utf-8"?>


     <application
         android:icon="@drawable/app_icon"
         android:label="@string/app_name"
         android:debuggable="true">
         
        <activity android:name="com.mars.plugins.Test" android:configChanges="keyboardHidden|orientation|screenSize|smallestScreenSize" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
        </activity>
         
     </application>
    
  2. You first create an instance of AndroidJavaClass for your activity, not sure why, but it is not needed.

  3. You create an AndroidJavaObject for your “Test” java class. This is an equivalent of creating that constructor in Java. You should not create an Activity by calling its constructor - the Android runtime creates the activity for you.

The code should be replaced to look like this:

 using UnityEngine;
 using System.Collections;
 
 public class TheTest : MonoBehaviour
 {
     // Use this for initialization
     void Start()
     { 
        using (var actClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
        {
            // UnityPlayer.currentActivity holds a reference to the activity (e.g: your Test class)
            var jo = actClass.GetStatic<AndroidJavaObject>("currentActivity");

            if (jo == null)
            {
                Debug.Log("jo is null");
                return;
            }
         }
     }
}