writing android wrapper for unity

Viewed 30

i am new to android and unity both. i want to write native wrapper and use in unity. to start with i have created simple framework in android (kotlin).

here is how kotlin code looks like:

class PluginInstance {
    fun initWithApp(id: String, name: String, completionBlock: (Boolean) -> Void) {
       if(id == "123" || name == "test") {
           completionBlock(true)
       } else {
           completionBlock(false)
       }
    }

    fun Add(i: Int, j: Int): Int {
        println("received data from unity: "+ i + " and " + j)
        return i * j
    }
}

i am able to call 'add' function from unity to android.

here is what c# code looks like:

public class PluginInit : MonoBehaviour
{
    AndroidJavaClass unityClass;
    AndroidJavaObject unityActivity;
    AndroidJavaObject _pluginInstance;

    void initializePlugIn(string pluginName)
    {

        unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        _pluginInstance = new AndroidJavaObject(pluginName);
        if (_pluginInstance == null)
        {
            UnityEngine.Debug.Log("Plugin instance error");
        }
        unityActivity = unityClass.GetStatic<AndroidJavaObject>("currentActivity");
        _pluginInstance.CallStatic("receivedUnityActivity", unityActivity);
    }

    public void Add()
    {
        if(_pluginInstance != null)
        {
            var result = _pluginInstance.Call<int>("Add", 50, 60);
            UnityEngine.Debug.Log("Add result from unity: " + result);
        }
    }

    [MonoPInvokeCallback(typeof(Action<bool>))]
    public static void completionBlock(bool status)
    {
        UnityEngine.Debug.Log("completionBlock status is: " + status);
    }

    public void initApp()
    {
        if (_pluginInstance != null)
        {
            _pluginInstance.Call("initWithApp", "123", "test", "completionBlock");
        }
    }
    // Start is called before the first frame update
    void Start()
    {
        initializePlugIn("com.voidstudio.unityplugin.PluginInstance");
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

but not able to call 'initWithApp', getting below error:

StackTrace  "java.lang.NoClassDefFoundError: Failed resolution of: Lkotlin/jvm/functions/Function1;\n\tat java.lang.reflect.Executable.getParameterTypesInternal(Native Method)\n\tat java.lang.reflect.Method.getParameterTypes(Method.java:186)\n\tat java.lang.Class.getDeclaredMethods(Class.java:1884)\n\tat com.unity3d.player.ReflectionHelper.getMethodID(Unknown Source:89)\n\tat com.unity3d.player.UnityPlayer.nativeRender(Native Method)\n\tat com.unity3d.player.UnityPlayer.access$300(Unknown Source:0)\n\tat com.unity3d.player.UnityPlayer$e$1.handleMessage(Unknown Source:95)\n\tat android.os.Handler.dispatchMessage(Handler.java:103)\n\tat android.os.Looper.loop(Looper.java:224)\n\tat com.unity3d.player.UnityPlayer$e.run(Unknown Source:20)\nCaused by: java.lang.ClassNotFoundException: Didn\'t find class \"kotlin.jvm.functions.Function1\" on path: DexPathList[[zip file \"/data/app/com.DefaultCompany.UnityTutorials1-fuYm25syH1tjvIopLqYbig==/base.apk\"],nativeLibraryDirectories=[/data/app/com.DefaultCompa…   string

next i came across 'AndroidJavaProxy' in unity: i tried to implement as below, getting error though:

Kotlin side code:

package com.voidstudio.unityplugin

import android.app.Activity;
import android.widget.Toast;

interface PluginCallback {
    fun onfinish(status: Boolean)
}

class PluginInstance {
    fun initWithApp(id: String, name: String, callback: PluginCallback) {
       if(id == "123" || name == "test") {
           callback.onfinish(true);
       } else {
           callback.onfinish(false);
       }
    }

    fun Add(i: Int, j: Int): Int {
        println("received data from unity: "+ i + " and " + j)
        return i * j
    }

    fun Toast(message: String?) {
        Toast.makeText(unityActivity, message, Toast.LENGTH_SHORT).show()
    }

    companion object {
        private var unityActivity: Activity? = null

        fun receivedUnityActivity(tActivity: Activity?) {
            unityActivity = tActivity
        }
    }
}

and C# side code:

public class AndroidPluginCallback : AndroidJavaProxy
{
    public AndroidPluginCallback() : base("com.voidstudio.unityplugin.PluginCallback") { }

    public void onfinish(bool status)
    {
        UnityEngine.Debug.Log("ENTER callback onFinish: " + status);
    }
}

public class PluginInit : MonoBehaviour
{
    AndroidJavaClass unityClass;
    AndroidJavaObject unityActivity;
    AndroidJavaObject _pluginInstance;

    void initializePlugIn(string pluginName)
    {

        unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        _pluginInstance = new AndroidJavaObject(pluginName);
        if (_pluginInstance == null)
        {
            UnityEngine.Debug.Log("Plugin instance error");
        }
        unityActivity = unityClass.GetStatic<AndroidJavaObject>("currentActivity");
        _pluginInstance.CallStatic("receivedUnityActivity", unityActivity);
    }

    public void Add()
    {
        if(_pluginInstance != null)
        {
            var result = _pluginInstance.Call<int>("Add", 50, 60);
            UnityEngine.Debug.Log("Add result from unity: " + result);
        }
    }

    public void initApp()
    {
        if (_pluginInstance != null)
        {
            _pluginInstance.Call("initWithApp", "123", "test", new AndroidPluginCallback());
        }
    }
    // Start is called before the first frame update
    void Start()
    {
        initializePlugIn("com.voidstudio.unityplugin.PluginInstance");
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

getting below error:

2022-09-15 20:03:21.464 28784-28947/com.DefaultCompany.UnityTutorials1 E/Unity: AndroidJavaException: java.lang.NoClassDefFoundError: Failed resolution of: Lkotlin/jvm/internal/Intrinsics;
    java.lang.NoClassDefFoundError: Failed resolution of: Lkotlin/jvm/internal/Intrinsics;
        at com.voidstudio.unityplugin.PluginInstance.initWithApp(Unknown Source:2)
        at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
        at com.unity3d.player.UnityPlayer.access$300(Unknown Source:0)
        at com.unity3d.player.UnityPlayer$e$1.handleMessage(Unknown Source:95)
        at android.os.Handler.dispatchMessage(Handler.java:103)
        at android.os.Looper.loop(Looper.java:224)
        at com.unity3d.player.UnityPlayer$e.run(Unknown Source:20)
     Caused by: java.lang.ClassNotFoundException: Didn't find class "kotlin.jvm.internal.Intrinsics" on path: DexPathList[[zip file "/data/app/com.DefaultCompany.UnityTutorials1-uQ0GB_qPkh_IKsYm1Ljl2g==/base.apk"],nativeLibraryDirectories=[/data/app/com.DefaultCompany.UnityTutorials1-uQ0GB_qPkh_IKsYm1Ljl2g==/lib/arm, /data/app/com.DefaultCompany.UnityTutorials1-uQ0GB_qPkh_IKsYm1Ljl2g==/base.ap

0 Answers
Related