Unity3d android java class

JAR plug-ins

JAR(Java Archive) plug-ins A set of code created outside of Unity that creates functionality in Unity. There are two kinds of plug-ins you can use in Unity: Managed plug-ins (managed .NET assemblies created with tools like Visual Studio) and Native plug-ins (platform-specific native code libraries). More info
See in Glossary are primarily used to enable interaction with the Android OS or to call methods written in Java from within your C# scripts A piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
See in Glossary .

They can only contain Java code (for example, they can’t contain Android resources), which makes their use very limited. To add a JAR plug-in to your project, copy the .jar file into any of your project folders, then select it in Unity to open the Import Settings in the Inspector A Unity window that displays information about the currently selected GameObject, asset or project settings, allowing you to inspect and edit the values. More info
See in Glossary window. Tick the Android checkbox to mark this .jar file as compatible with Android:

JAR plug-in import settings as displayed in the Inspector window

Using Java plug-ins

Unity uses the Java Native Interface (JNI) both when calling code from Java and when interacting with Java or the Java VM(Virtual Machine) from native code or C# scripts.

Java source files as plug-ins

When using the Gradle build system, you can avoid creating JAR files. To do this:

  1. Drop the .java file into your Unity project as a plug-in.
  2. In the Plugin Inspector, mark the plug-in for the Android platform.
  3. When building for Android, make sure Gradle An Android build system that automates several build processes. This automation means that many common build errors are less likely to occur. More info
    See in Glossary is set as your Build System in the Build Settings.

Unity copies the java file to the Gradle project and builds with it.

Using your Java plug-in from native (C/C++) code

Note: This information in this section requires advanced knowledge of the Android Java Native Interface (JNI).

To access your Java code from C or C++ plug-ins, you need access to the Java VM. Add the following method to your C/C++ code to access the Java VM.

It is beyond the scope of this document to explain JNI completely, but this method usually involves finding the class definition, resolving the constructor ( ) method and creating a new object instance, as shown in this example:

Using your Java plug-in from C# scripts with helper classes

Note: This information in this section requires advanced knowledge of the Android Java Native Interface (JNI).

The AndroidJNIHelper and AndroidJNI Unity API classes are used as a wrapper around a “raw” JNI interface.

The AndroidJavaObject and AndroidJavaClass Unity API classes automate a lot of tasks when using JNI calls, and they also use caching to make calls to Java faster. The combination of AndroidJavaObject and AndroidJavaClass is built on top of AndroidJNI and AndroidJNIHelper , but also has some additional functionality. These classes also have static methods that are used to access static members of Java classes.

There are three ways to make Java JNI calls from your C# scripts:

  • raw JNI through the AndroidJNI methods ;
  • AndroidJNIHelper class together with AndroidJNI ;
  • AndroidJavaObject and AndroidJavaClass classes as the most convenient high-level APIs.

UnityEngine.AndroidJNI is a wrapper for the JNI calls available in C (as described above). All methods in this class are static and have a 1:1 mapping to the Java Native Interface.

UnityEngine.AndroidJNIHelper provides helper functionality used by the next level, which is exposed as public methods and might be useful in special cases.

Instances of UnityEngine.AndroidJavaObject and UnityEngine.AndroidJavaClass have a one-to-one mapping to an instance of java.lang.Object and java.lang.Class (or their subclasses) on the Java side, respectively. They essentially provide 3 types of interaction with the Java side:

Get the value of a field

Set the value of a field

The call is separated into two categories: A call to a ‘void’ method, and call to a method with non-void return type. A generic type is used to represent the return type of those methods which return a non-void type. The Get and Set always take a generic type representing the field type.

Examples

Example 1

This example creates an instance of java.lang.String initialized with a string, and retrieves the hash value for that string.

The AndroidJavaObject constructor takes at least one parameter — the name of the class of to construct an instance of. Any parameters after the class name are for the constructor call on the object, in this case the string “some_string”. The subsequent call to hashCode() returns an ‘int’ which is is used as the generic type parameter to the call method in this example.

Читайте также:  Лучший видеозахват для андроид

Note: A nested Java class cannot be instantiated using dotted notation. Inner classes must use the $ separator. Use android.view.ViewGroup$LayoutParams or android/view/ViewGroup$LayoutParams , where LayoutParams class is nested in ViewGroup class.

Example 2

This example shows how to get the cache directory for the current application in C# without using plug-ins:

This example starts with AndroidJavaClass instead of AndroidJavaObject in order to access a static member of com.unity3d.player.UnityPlayer rather than create a new object. Then the static field “currentActivity” is accessed but this time AndroidJavaObject is used as the generic parameter. This is because the actual field type android.app.Activity is a subclass of java.lang.Object , and any non-primitive type must be accessed as AndroidJavaObject . The exceptions to this rule are strings, which are accessed directly even though they don’t represent a primitive type in Java.

getCacheDir() can then be called on the Activity object to get the File object representing the cache directory, getCanonicalPath() can then be called to get a string representation.

Unity provides access to the application’s cache and file directory with Application.temporaryCachePath and Application.persistentDataPath APIs.

Example 3

This example shows how to pass data from Java to Unity using UnitySendMessage .

The Java class com.unity3d.player.UnityPlayer has a static method UnitySendMessage , equivalent to the iOS Apple’s mobile operating system. More info
See in Glossary method: UnitySendMessage . It is used in Java to pass data to Unity.

Although UnitySendMessage is called from within Unity, it relays the message using Java, then Java calls back to the native/Unity code to deliver the message to the object named “Main Camera A component which creates an image of a particular viewpoint in your scene. The output is either drawn to the screen or captured as a texture. More info
See in Glossary ”. This object has a script attached which contains a method called JavaMessage .

Best practice when using Java plug-ins with Unity

AndroidJavaObject and AndroidJavaClass are computationally expensive methods (as are any methods that use raw JNI). Keep the number of transitions between managed and native/Java code to a minimum, for better performance and also code clarity.

The Mono garbage collector should release all created instances of AndroidJavaObject and AndroidJavaClass after use, but it is advisable to keep them in a using()<> statement to ensure they are deleted as soon as possible. Without this, you cannot be sure when they are be destroyed. If you set AndroidJNIHelper.debug to true, you will see a record of the garbage collector’s activity in the debug output.

2018–03–20 Page published

Updated features in 5.5

Support for Java source file plug-ins added for Android player in 2018.2 NewIn20182

Источник

AndroidJavaObject

class in UnityEngine

Success!

Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable.

Submission failed

For some reason your suggested change could not be submitted. Please try again in a few minutes. And thank you for taking the time to help us improve the quality of Unity Documentation.

Description

AndroidJavaObject is the Unity representation of a generic instance of java.lang.Object.

It can be used as type-less interface to an instance of any Java class. Note: this API can be used from custom thread, but requires that thread to be attached to JVM first, see AndroidJNI.AttachCurrentThread.

Constructors

AndroidJavaObject Construct an AndroidJavaObject based on the name of the class.

Public Methods

Call Calls a Java method on an object (non-static).
CallStatic Call a static Java method on a class.
Dispose IDisposable callback.
Get Get the value of a field in an object (non-static).
GetRawClass Retrieves the raw jclass pointer to the Java class.Note: Using raw JNI functions requires advanced knowledge of the Android Java Native Interface (JNI). Please take note.
GetRawObject Retrieves the raw jobject pointer to the Java object.Note: Using raw JNI functions requires advanced knowledge of the Android Java Native Interface (JNI). Please take note.
GetStatic Get the value of a static field in an object type.
Set Set the value of a field in an object (non-static).
SetStatic Set the value of a static field in an object type.

Is something described here not working as you expect it to? It might be a Known Issue. Please check with the Issue Tracker at issuetracker.unity3d.com.

Copyright ©2021 Unity Technologies. Publication Date: 2021-11-26.

Источник

Building Plugins for Android

This page describes Native Code Plugins for Android.

Building a Plugin for Android

To build a plugin for Android, you should first obtain the Android NDK and familiarize yourself with the steps involved in building a shared library.

If you are using C++ (.cpp) to implement the plugin you must ensure the functions are declared with C linkage to avoid name mangling issues.

Using Your Plugin from C#

Once built, the shared library should be copied to the Assets->Plugins->Android folder. Unity will then find it by name when you define a function like the following in the C# script:-

Please note that PluginName should not include the prefix (‘lib’) nor the extension (‘.so’) of the filename. You should wrap all native code methods with an additional C# code layer. This code should check Application.platform and call native methods only when the app is running on the actual device; dummy values can be returned from the C# code when running in the Editor. You can also use platform defines to control platform dependent code compilation.

Android Library Projects

You can drop pre-compiled Android library projects into the Assets->Plugins->Android folder. Pre-compiled means all .java files must have been compiled into jar files located in either the bin/ or the libs/ folder of the project. AndroidManifest.xml from these folders will get automatically merged with the main manifest file when the project is built.

Читайте также:  Color setting android что это

Deployment

For cross platform deployment, your project should include plugins for each supported platform (ie, libPlugin.so for Android, Plugin.bundle for Mac and Plugin.dll for Windows). Unity automatically picks the right plugin for the target platform and includes it with the player.

For specific Android platform (armv7, x86), the libraries (lib*.so) should be placed in the following:

Using Java Plugins

The Android plugin mechanism also allows Java to be used to enable interaction with the Android OS.

Building a Java Plugin for Android

There are several ways to create a Java plugin but the result in each case is that you end up with a .jar file containing the .class files for your plugin. One approach is to download the JDK, then compile your .java files from the command line with javac. This will create .class files which you can then package into a .jar with the jar command line tool. Another option is to use the Eclipse IDE together with the ADT.

Note: Unity expects Java plugins to be built using JDK v1.6. If you are using v1.7, you should include “-source 1.6 -target 1.6” in the command line options to the compiler.

Using Your Java Plugin from Native Code

Once you have built your Java plugin (.jar) you should copy it to the Assets->Plugins->Android folder in the Unity project. Unity will package your .class files together with the rest of the Java code and then access the code using the Java Native Interface (JNI). JNI is used both when calling native code from Java and when interacting with Java (or the JavaVM) from native code.

To find your Java code from the native side you need access to the Java VM. Fortunately, that access can be obtained easily by adding a function like this to your C/C++ code:

This is all that is needed to start using Java from C/C++. It is beyond the scope of this document to explain JNI completely. However, using it usually involves finding the class definition, resolving the constructor ( ) method and creating a new object instance, as shown in this example:-

Using Your Java Plugin with helper classes

AndroidJNIHelper and AndroidJNI can be used to ease some of the pain with raw JNI.

AndroidJavaObject and AndroidJavaClass automate a lot of tasks and also use cacheing to make calls to Java faster. The combination of AndroidJavaObject and AndroidJavaClass builds on top of AndroidJNI and AndroidJNIHelper, but also has a lot of logic in its own right (to handle the automation). These classes also come in a ‘static’ version to access static members of Java classes.

You can choose whichever approach you prefer, be it raw JNI through AndroidJNI class methods, or AndroidJNIHelper together with AndroidJNI and eventually AndroidJavaObject/AndroidJavaClass for maximum automation and convenience.

UnityEngine.AndroidJNI is a wrapper for the JNI calls available in C (as described above). All methods in this class are static and have a 1:1 mapping to the Java Native Interface. UnityEngine.AndroidJNIHelper provides helper functionality used by the next level, but is exposed as public methods because they may be useful for some special cases.

Instances of UnityEngine.AndroidJavaObject and UnityEngine.AndroidJavaClass have a one-to-one mapping to an instance of java.lang.Object and java.lang.Class (or subclasses thereof) on the Java side, respectively. They essentially provide 3 types of interaction with the Java side:-

  • Call a method
  • Get the value of a field
  • Set the value of a field

The Call is separated into two categories: Call to a ‘void’ method, and Call to a method with non-void return type. A generic type is used to represent the return type of those methods which return a non-void type. The Get and Set always take a generic type representing the field type.

Example 1

Here, we’re creating an instance of java.lang.String, initialized with a string of our choice and retrieving the hash value for that string.

The AndroidJavaObject constructor takes at least one parameter, the name of class for which we want to construct an instance. Any parameters after the class name are for the constructor call on the object, in this case the string “some_string”. The subsequent Call to hashCode() returns an ‘int’ which is why we use that as the generic type parameter to the Call method.

Note: You cannot instantiate a nested Java class using dotted notation. Inner classes must use the $ separator, and it should work in both dotted and slashed format. So \[android.view.ViewGroup$LayoutParams __or__ android/view/ViewGroup$LayoutParams__ can be used, where a __LayoutParams__ class is nested in a __ViewGroup\] class.

Example 2

One of the plugin samples above shows how to get the cache directory for the current application. This is how you would do the same thing from C# without any plugins:-

In this case, we start with AndroidJavaClass instead of AndroidJavaObject because we want to access a static member of com.unity3d.player.UnityPlayer rather than create a new object (an instance is created automatically by the Android UnityPlayer). Then we access the static field “currentActivity” but this time we use AndroidJavaObject as the generic parameter. This is because the actual field type (android.app.Activity) is a subclass of java.lang.Object, and any non-primitive type must be accessed as AndroidJavaObject. The exceptions to this rule are strings, which can be accessed directly even though they don’t represent a primitive type in Java.

Читайте также:  Nfs no limits android машины

After that it is just a matter of traversing the Activity through getCacheDir() to get the File object representing the cache directory, and then calling getCanonicalPath() to get a string representation.

Of course, nowadays you don’t need to do that to get the cache directory since Unity provides access to the application’s cache and file directory with Application.temporaryCachePath and Application.persistentDataPath.

Example 3

Finally, here is a trick for passing data from Java to script code using UnitySendMessage.

The Java class com.unity3d.player.UnityPlayer now has a static method UnitySendMessage, equivalent to the iOS UnitySendMessage function on the native side. It can be used in Java to pass data to script code.

Here though, we call it directly from script code, which essentially relays the message on the Java side. This then calls back to the native/Unity code to deliver the message to the object named “Main Camera”. This object has a script attached which contains a method called “JavaMessage”.

Best practice when using Java plugins with Unity

As this section is mainly aimed at people who don’t have comprehensive JNI, Java and Android experience, we assume that the AndroidJavaObject/AndroidJavaClass approach has been used for interacting with Java code from Unity.

The first thing to note is that any operation you perform on an AndroidJavaObject or AndroidJavaClass is computationally expensive (as is the raw JNI approach). It is highly advisable to keep the number of transitions between managed and native/Java code to a minimum, for the sake of performance and also code clarity.

You could have a Java method to do all the actual work and then use AndroidJavaObject / AndroidJavaClass to communicate with that method and get the result. However, it is worth bearing in mind that the JNI helper classes try to cache as much data as possible to improve performance.

The Mono garbage collector should release all created instances of AndroidJavaObject and AndroidJavaClass after use, but it is advisable to keep them in a using()<> statement to ensure they are deleted as soon as possible. Without this, you cannot be sure when they will be destroyed. If you set AndroidJNIHelper.debug to true, you will see a record of the garbage collector’s activity in the debug output.

You can also call the .Dispose() method directly to ensure there are no Java objects lingering. The actual C# object might live a bit longer, but will be garbage collected by mono eventually.

Extending the UnityPlayerActivity Java Code

With Unity Android it is possible to extend the standard UnityPlayerActivity class (the primary Java class for the Unity Player on Android, similar to AppController.mm on Unity iOS).

An application can override any and all of the basic interaction between Android OS and Unity Android. You can enable this by creating a new Activity which derives from UnityPlayerActivity (UnityPlayerActivity.java can be found at /Applications/Unity/Unity.app/Contents/PlaybackEngines/AndroidPlayer/src/com/unity3d/player on Mac and usually at C:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\src\com\unity3d\player on Windows).

To do this, first locate the classes.jar shipped with Unity Android. It is found in the installation folder (usually C:\Program Files\Unity\Editor\Data (on Windows) or /Applications/Unity (on Mac)) in a sub-folder called PlaybackEngines/AndroidPlayer/Variations/mono or il2cpp/Development or Release/Classes/. Then add classes.jar to the classpath used to compile the new Activity. The resulting .class file(s) should be compressed into a .jar file and placed in the Assets->Plugins->Android folder. Since the manifest dictates which activity to launch it is also necessary to create a new AndroidManifest.xml. The AndroidManifest.xml file should also be placed in the Assets->Plugins->Android folder (placing a custom manifest completely overrides the default Unity Android manifest).

The new activity could look like the following example, OverrideExample.java:

And this is what the corresponding AndroidManifest.xml would look like:

UnityPlayerNativeActivity

It is also possible to create your own subclass of UnityPlayerNativeActivity . This will have much the same effect as subclassing UnityPlayerActivity but with improved input latency. Be aware, though, that NativeActivity was introduced in Gingerbread and does not work with older devices. Since touch/motion events are processed in native code, Java views would normally not see those events. There is, however, a forwarding mechanism in Unity which allows events to be propagated to the DalvikVM. To access this mechanism, you need to modify the manifest file as follows:-

Note the “.OverrideExampleNative” attribute in the activity element and the two additional meta-data elements. The first meta-data is an instruction to use the Unity library libunity.so. The second enables events to be passed on to your custom subclass of UnityPlayerNativeActivity.

Examples

Native Plugin Sample

A simple example of the use of a native code plugin can be found here

This sample demonstrates how C code can be invoked from a Unity Android application. The package includes a scene which displays the sum of two values as calculated by the native plugin. Please note that you will need the Android NDK to compile the plugin.

Java Plugin Sample

An example of the use of Java code can be found here

This sample demonstrates how Java code can be used to interact with the Android OS and how C++ creates a bridge between C# and Java. The scene in the package displays a button which when clicked fetches the application cache directory, as defined by the Android OS. Please note that you will need both the JDK and the Android NDK to compile the plugins.

Here is a similar example but based on a prebuilt JNI library to wrap the native code into C#.

Источник

Оцените статью