[Unity3d] Communication between Unity and Android

In the development of unity or sdk, communication between unity and the native layer of the mobile terminal is often encountered. Here, the communication between them is sorted out.

For communication between Unity and iOS, refer to [Unity3d] Communication between Unity and iOS

Unity (c#) calls Android

(1), write Java code

In fact, any existing Java code can be called by c#, unlike iOS, which generally needs to be extern "C"modified in advance.

For example, the content of MyJavaClass in Java is as follows:

package com.devnn.demo;

public class MyJavaClass{
    
    

	private static MyJavaClass instance=new MyJavaClass();
	
	public static getInstance(){
    
    
  		return instance;
	}
	
	public String test(String param){
    
    
		return "This message is from Android!"
	}
}

getInstanceAnd testcan be called by c#.

If it is code written in kotlin, it can also be called by c#. Pay attention to the class path. It is best to view the bytecode or decompile it into Java to view the path.
In addition, after using kotlin, you need to add an additional kotlin runtime library, for example:
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.20"

In order to facilitate the export of jar or aar, it is recommended to write in the library project.

(2) Package the Java code into aar or jar and copy it to the unity project

Copy the packaged aar or jar to Assetsthe directory or subdirectory of the Unity project.

In fact, it can be copied to Assetsany location under the directory of the unity project, and aar and jar will be automatically depended on by unity as lib. (It can be seen from exporting the gradle project)

(The unity version used by the author is 2019.4. I don’t know if the previous version can be in any position.)

For the convenience of management, the above aar/jar is generally placed Assets/Plugins/Androidin .

(3), calling Java code in c#

C# provides two classes that can call Java code:

AndroidJavaClass.cs
AndroidJavaObject.cs

They are all in UnityEnginea namespace.

AndroidJavaClassis inherited from AndroidJavaClass.

The difference between these two classes is generally not used by us, and any one of them can be used.

The way to use is very simple, pass in the full path of the Java class in the construction method, and then call the Call method to call the Java instance method or CallStatic to call the Java static method. Write the type returned by Java in the method generic.

Sample code:

 	//实例化AndroidJavaClass,传入Java类路径
 	AndroidJavaClass jc = new AndroidJavaClass("com.devnn.demo.MyJavaClass");
 
	 //如果找不到Java类,返回null
	if(jc == null) return;          

	//调用Java类的getInstance方法获取实例
	AndroidJavaObject jo = jc.CallStatic<AndroidJavaObject>("getInstance");

	 //如果找不到Java方法,返回null
	if (jo == null) return;

	string param = "Hello,Android!";

	string result = jo.Call<string>("test", param); //调用test方法,返回值是字符串。
	

Android calls Unity (c#)

It is relatively simple to call c# on Android, just use the following method.

   UnityPlayer.UnitySendMessage("MyTestObject", "TestFunc","msg");

Need to rely on the classes.jar of unity, the location is in the unity installation directory: AndroidPlayer/Variations/mono/Release/Classes/classes.jar.

When the Unity project exports the Android project, it has already relied on this jar by default, and the new Android project needs to import the above jar package.

The classes.jar of this unity is not currently open source, and decompiled to see the obfuscated code.

UnitySendMessageThe source code of the method is as follows:

//com.unity3d.player.UnityPlayer.class
    public static void UnitySendMessage(String var0, String var1, String var2) {
    
    
        if (!n.c()) {
    
    
            g.Log(5, "Native libraries not loaded - dropping message for " + var0 + "." + var1);
        } else {
    
    
            try {
    
    
                nativeUnitySendMessage(var0, var1, var2.getBytes("UTF-8"));
            } catch (UnsupportedEncodingException var3) {
    
    
            }
        }
    }

    private static native void nativeUnitySendMessage(String var0, String var1, byte[] var2);

It can be seen that this is achieved through jni.

The first parameter var0 represents the name of the object GameObject in unity. Note that it is not the name of the c# script or the class name.

As shown below:
insert image description here

The second parameter var1 indicates the name of the method in the c# script mounted by this object.

The third parameter indicates that var2 indicates the data received by this method.

For example, the above object MyTestObjectmounts MyScript.c#the script (as shown above), and MyScript.c#there is a TestFuncmethod in it:

using UnityEngine;

public class MyScript : MonoBehaviour
{
    
    

    private void TestFunc(string content)
 	{
    
    
 		//这里是接收Android调用的实现
	}  
             
}

UnitySendMessage("MyTestObject", "TestFunc", "msg")Then the method of calling c# in Android TestFuncwill be executed.

If there are multiple parameters to be sent, it is recommended to use the json format.

Guess you like

Origin blog.csdn.net/devnn/article/details/129099563