在自定义 Unity Android 插件上调用非静态方法
Call non-static methods on custom Unity Android Plugins
我正在尝试了解如何为 Android 构建我自己的 Android 插件。
我实现了在 Java class(在 AndroidStudio 上创建的那个)上调用静态方法,但我真的不能调用非静态方法。
我查看了这些链接:
https://answers.unity.com/questions/884503/cant-call-non-static-method-in-androidjavaclass.html
http://leoncvlt.com/blog/a-primer-on-android-plugin-development-in-unity/
https://answers.unity.com/questions/1327186/how-to-get-intent-data-for-unity-to-use.html
- how to call Non-static method from Unity Android Plugin?
但是 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:
Taras Leskiv 建议将 UnityPlayer.Get 改为
UnityPlayer.Get静态,但随后出现以下错误:
错误:java.lang.NoSuchMethodError:class Ljava.lang.Object;
中没有名称='SayHi' 签名='()V' 的非静态方法
- Proguard 未激活。
可能与 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
很明显(不适合我)导致错误垃圾邮件无法找到签名,所以软件无法读取那些 类。
我正在尝试了解如何为 Android 构建我自己的 Android 插件。
我实现了在 Java class(在 AndroidStudio 上创建的那个)上调用静态方法,但我真的不能调用非静态方法。
我查看了这些链接:
https://answers.unity.com/questions/884503/cant-call-non-static-method-in-androidjavaclass.html
http://leoncvlt.com/blog/a-primer-on-android-plugin-development-in-unity/
https://answers.unity.com/questions/1327186/how-to-get-intent-data-for-unity-to-use.html
- how to call Non-static method from Unity Android Plugin?
但是 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:
Taras Leskiv 建议将 UnityPlayer.Get 改为 UnityPlayer.Get静态,但随后出现以下错误:
错误:java.lang.NoSuchMethodError:class Ljava.lang.Object;
中没有名称='SayHi' 签名='()V' 的非静态方法- Proguard 未激活。
可能与 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
很明显(不适合我)导致错误垃圾邮件无法找到签名,所以软件无法读取那些 类。