在自定义 Unity Android 插件上调用非静态方法

Call non-static methods on custom Unity Android Plugins

我正在尝试了解如何为 Android 构建我自己的 Android 插件。

我实现了在 Java class(在 AndroidStudio 上创建的那个)上调用静态方法,但我真的不能调用非静态方法。

我查看了这些链接:

但是 none 有效。

我正在尝试通过 Unity 的按钮接听电话,例如:

AndroidJavaClass UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = UnityPlayer.Get<AndroidJavaObject>("currentActivity");
currentActivity.Call("SayHi");

我在 Android 上的 activity 看起来像:

public class MainActivity extends UnityPlayerActivity {
    private static final String TAG = "LibraryTest";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "Created!");
    }

    public void SayHi()
    {
        Log.d(TAG, "HI_");
    }
}

我的 ADB 正在抛出此消息:

我也尝试调用而不是 UnityPlayer 调用它:

AndroidJavaClass pluginClass = new AndroidJavaClass("com.example.eric.librarytest.MainActivity");

编辑: 这是我的 AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.eric.librarytest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="24"
        android:targetSdkVersion="28" />

    <application android:label="@string/app_name" >
        <activity
            android:name="com.example.eric.librarytest.MainActivity"
            android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

但对非静态方法也不起作用,如果我这样做,它只对静态方法起作用 pluginClass.CallStatic(""),知道吗?

编辑 2:

可能与 java 继承有关:您的 currentActivity AndroidJavaObject 是 class com.unity3d.player.UnityPlayer 但此 class 没有 SayHi 方法,在调用方法之前,您应该将对象转换为 MainActivity

当你这样做时:

AndroidJavaClass UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = UnityPlayer.Get<AndroidJavaObject>("currentActivity");
currentActivity.Call("SayHi");

它不起作用,因为 currentActivity 字段是静态的,你应该做的是:

AndroidJavaClass UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = UnityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
currentActivity.Call("SayHi");

注意UnityPlayer.GetStatic部分

这是我的一个插件的其他便利片段:

    static AndroidJavaObject _activity;

    public static AndroidJavaObject Activity
    {
        get
        {
            if (_activity == null)
            {
                var unityPlayer = new AndroidJavaClass(C.ComUnity3DPlayerUnityPlayer);
                _activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
            }
            return _activity;
        }
    }

您需要做的就是在 activity class:

中声明您自己的静态上下文
public class MainActivity extends UnityPlayerActivity {
    private static final String TAG = "LibraryTest";
    public static Context mContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = this;
        Log.d(TAG, "Created!");
    }

    public void SayHi()
    {
        Log.d(TAG, "HI_");
    }
}

然后像这样从 C# 调用任何非静态方法:

public static void AndroidCallFunction()
{
    using (AndroidJavaClass javaClass = new AndroidJavaClass("com.example.eric.librarytest.MainActivity"))
    {
        using (AndroidJavaObject activity = javaClass.GetStatic<AndroidJavaObject>("mContext"))
        {
            activity.Call("SayHi");
        }
    }
}

NO 其他方法可以直接从 java 代码调用方法。您可以使用 AndroidJavaProxy 和 Broadcast 命令实现自己的消息传递系统,甚至根本不需要 activity,但这是另一个问题。

我的代码是正确的,问题是项目结构。

我的项目是这样的:

Assets
├── Plugins
│   ├── classes.jar

应该是这样的:

Assets
├── Plugins
│   ├── Android
│   │   ├── classes.jar

很明显(不适合我)导致错误垃圾邮件无法找到签名,所以软件无法读取那些 类。