Unity Android :没有带名称的非静态方法



我正在为unity制作一个Android插件演示,当我单击按钮时,它将启动另一个应用程序。我可以构建一个apk并将其安装到我的设备上。但是,当我单击该按钮时,什么也没发生,只是说:Unity:AndroidJavaException:java.lang.NoSuchMethodError:没有名称='shareToWX' 的非静态方法

这是安卓代码:

public class WXEntryActivity extends UnityPlayerActivity implements IWXAPIEventHandler {
private static final String APP_ID="";
private static final String APP_SECRET="";
private static IWXAPI api;
private static final int WXSceneSession=0;
private static final int WXSceneTimeLine=1;
private static final int WXSceneFavorite=2;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
api= WXAPIFactory.createWXAPI(this,APP_ID,true);
api.registerApp(APP_ID);
api.handleIntent(getIntent(),this);
}

public void shareToWX(String text,int scene){
WXWebpageObject webpage=new WXWebpageObject();
webpage.webpageUrl="www.baidu.com";
WXMediaMessage msg =new WXMediaMessage(webpage);
msg.title="网页标题";
msg.description="描述";
Bitmap thumb=BitmapFactory.decodeResource(getResources(), R.drawable.test);
//msg.thumbData=
SendMessageToWX.Req req=new SendMessageToWX.Req();
req.transaction=buildTransaction("webpage");
req.message=msg;
switch (scene){
case WXSceneFavorite:
req.scene=SendMessageToWX.Req.WXSceneFavorite;
break;
case WXSceneTimeLine:
req.scene=SendMessageToWX.Req.WXSceneTimeline;
break;
case WXSceneSession:
req.scene=SendMessageToWX.Req.WXSceneSession;
break;
}
api.sendReq(req);
}

这是我的统一代码:

public class test : MonoBehaviour {
public GameObject btnObj;
// Use this for initialization
void Start () {
Button button = btnObj.GetComponent<Button>();
button.onClick.AddListener(share);
}
// Update is called once per frame
void Update () {
}
void share()
{
AndroidJavaClass jc = new    AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
jo.Call("shareToWX", "unity test",0);
}
}

清单.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yrgame.wjqpyx">
<application android:allowBackup="true" android:label="@string/app_name"
android:supportsRtl="true">
<activity android:name="com.yrgame.wjqpyx.wxapi.WXEntryActivity"/>
</application>
</manifest>

错误:

I/Unity: AndroidJavaException: java.lang.NoSuchMethodError: no non-static method with name='shareToWX' signature='(Ljava/lang/String;I)V' in class Lcom.unity3d.player.UnityPlayerActivity;
java.lang.NoSuchMethodError: no non-static method with name='shareToWX' signature='(Ljava/lang/String;I)V' in class Lcom.unity3d.player.UnityPlayerActivity;
at com.unity3d.player.ReflectionHelper.getMethodID(Unknown Source)
at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
at com.unity3d.player.UnityPlayer.c(Unknown Source)
at com.unity3d.player.UnityPlayer$c$1.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:136)
at com.unity3d.player.UnityPlayer$c.run(Unknown Source)
at UnityEngine.AndroidJNISafe.CheckException () [0x00000] in <filename unknown>:0 
at UnityEngine.AndroidJNISafe.CallStaticObjectMethod (IntPtr clazz, IntPtr methodID, UnityEngine.jvalue[] args) [0x00000] in <filename unknown>:0 
at UnityEngine.AndroidReflection.GetMetho

请帮我一把!!

我相信这是因为您没有正确声明您的清单,因此它仍在使用正常的 UnityPlayerActivity 而不是您的自定义清单。

具体地将其添加到清单的活动标记中:

<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

查看 Unity 在此处给出的示例:https://docs.unity3d.com/Manual/AndroidUnityPlayerActivity.html

Unity Code(C#(

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class MainManager : MonoBehaviour
{
public Button button;
// Start is called before the first frame update
void Start()
{
button.onClick.AddListener(() =>
{
CallAndroidMethod("receiveStr", "howru");
});
}
// 첫 번쨰 방식
public static void CallAndroidMethod(string methodName, string str)
{
using (var clsUnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) // "com.pingtech.swingtracker.UnityPlayerActivity"))
{
using (var objActivity = clsUnityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
{
objActivity.Call(methodName, str);
}
}
}
public static void sendStr(string str)
{
CallAndroidMethod("receiveStr", str);
}
}

安卓代码(Java(

import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.os.Process;
public class UnityPlayerActivity extends Activity implements IUnityPlayerLifecycleEvents
{
protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code
// Override this in your custom UnityPlayerActivity to tweak the command line arguments passed to the Unity Android Player
// The command line arguments are passed as a string, separated by spaces
// UnityPlayerActivity calls this from 'onCreate'
// Supported: -force-gles20, -force-gles30, -force-gles31, -force-gles31aep, -force-gles32, -force-gles, -force-vulkan
// See https://docs.unity3d.com/Manual/CommandLineArguments.html
// @param cmdLine the current command line arguments, may be null
// @return the modified command line string or null
protected String updateUnityCommandLineArguments(String cmdLine)
{
return cmdLine;
}
// Setup activity layout
@Override protected void onCreate(Bundle savedInstanceState)
{
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
String cmdLine = updateUnityCommandLineArguments(getIntent().getStringExtra("unity"));
getIntent().putExtra("unity", cmdLine);
mUnityPlayer = new UnityPlayer(this, this);
setContentView(mUnityPlayer);
mUnityPlayer.requestFocus();
}
// When Unity player unloaded move task to background
@Override public void onUnityPlayerUnloaded() {
moveTaskToBack(true);
}
// Callback before Unity player process is killed
@Override public void onUnityPlayerQuitted() {
}
@Override protected void onNewIntent(Intent intent)
{
// To support deep linking, we need to make sure that the client can get access to
// the last sent intent. The clients access this through a JNI api that allows them
// to get the intent set on launch. To update that after launch we have to manually
// replace the intent with the one caught here.
setIntent(intent);
mUnityPlayer.newIntent(intent);
}
// Quit Unity
@Override protected void onDestroy ()
{
mUnityPlayer.destroy();
super.onDestroy();
}
// If the activity is in multi window mode or resizing the activity is allowed we will use
// onStart/onStop (the visibility callbacks) to determine when to pause/resume.
// Otherwise it will be done in onPause/onResume as Unity has done historically to preserve
// existing behavior.
@Override protected void onStop()
{
super.onStop();
if (!MultiWindowSupport.getAllowResizableWindow(this))
return;
mUnityPlayer.pause();
}
@Override protected void onStart()
{
super.onStart();
if (!MultiWindowSupport.getAllowResizableWindow(this))
return;
mUnityPlayer.resume();
}
// Pause Unity
@Override protected void onPause()
{
super.onPause();
MultiWindowSupport.saveMultiWindowMode(this);
if (MultiWindowSupport.getAllowResizableWindow(this))
return;
mUnityPlayer.pause();
}
// Resume Unity
@Override protected void onResume()
{
super.onResume();
if (MultiWindowSupport.getAllowResizableWindow(this) && !MultiWindowSupport.isMultiWindowModeChangedToTrue(this))
return;
mUnityPlayer.resume();
}
// Low Memory Unity
@Override public void onLowMemory()
{
super.onLowMemory();
mUnityPlayer.lowMemory();
}
// Trim Memory Unity
@Override public void onTrimMemory(int level)
{
super.onTrimMemory(level);
if (level == TRIM_MEMORY_RUNNING_CRITICAL)
{
mUnityPlayer.lowMemory();
}
}
// This ensures the layout will be correct.
@Override public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
mUnityPlayer.configurationChanged(newConfig);
}
// Notify Unity of the focus change.
@Override public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
mUnityPlayer.windowFocusChanged(hasFocus);
}
// For some reason the multiple keyevent type is not supported by the ndk.
// Force event injection by overriding dispatchKeyEvent().
@Override public boolean dispatchKeyEvent(KeyEvent event)
{
if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
return mUnityPlayer.injectEvent(event);
return super.dispatchKeyEvent(event);
}
// Pass any events not handled by (unfocused) views straight to UnityPlayer
@Override public boolean onKeyUp(int keyCode, KeyEvent event)     { return mUnityPlayer.injectEvent(event); }
@Override public boolean onKeyDown(int keyCode, KeyEvent event)   { return mUnityPlayer.injectEvent(event); }
@Override public boolean onTouchEvent(MotionEvent event)          { return mUnityPlayer.injectEvent(event); }
/*API12*/ public boolean onGenericMotionEvent(MotionEvent event)  { return mUnityPlayer.injectEvent(event); }
public void receiveStr(String str) {
Log.e(this.toString(), "receiveStr=" + str);
}
}

Unity 方法代码和 Android 方法代码必须匹配。 例如: Unity:"receiveStr" == Android="receiveStr">

最新更新