簡體   English   中英

AndroidJavaException: java.lang.NoSuchMethodError: no non-static method with name='getStatusCode' signature='()I'

[英]AndroidJavaException: java.lang.NoSuchMethodError: no non-static method with name='getStatusCode' signature='()I'

當我嘗試使用 Google Play 游戲插件(即使我已登錄)保存或加載我的游戲時,logcat 會向我顯示:這個錯誤 嘗試了不同的方法來保存游戲,但它一次又一次地顯示。 PS成就和排行榜工作正常。

這是我調用保存和加載過程的腳本:

     #if UNITY_ANDROID
 using UnityEngine;
 using System;
 using System.Collections.Generic;
 //gpg
 using GooglePlayGames;
 using GooglePlayGames.BasicApi;
 using GooglePlayGames.BasicApi.SavedGame;
 //for encoding
 using System.Text;
 //for extra save ui
 using UnityEngine.SocialPlatforms;
 //for text, remove
 using UnityEngine.UI;
 
 public class SaveManager :MonoBehaviour{
 
     private static SaveManager _instance;
     public static SaveManager Instance{
         get{
             if (_instance == null) {
                 _instance = new SaveManager();
             }
             return _instance;
         }
     }
 
     //keep track of saving or loading during callbacks.
     private bool m_saving;
     //save name. This name will work, change it if you like.
     private static string m_saveName = "game_save_name";
     //This is the saved file. Put this in seperate class with other variables for more advanced setup. Remember to change merging, toBytes and fromBytes for more advanced setup.
     private string saveString = "";
 
     //check with GPG (or other*) if user is authenticated. *e.g. GameCenter
     private bool Authenticated {
         get {
             return Social.Active.localUser.authenticated;
         }
     }
 
     //merges loaded bytearray with old save
     private void ProcessCloudData(byte[] cloudData) {
         if (cloudData == null) {
             Debug.Log("No data saved to the cloud yet...");
             return;
         }
         Debug.Log("Decoding cloud data from bytes.");
         string progress = FromBytes(cloudData);
         Debug.Log("Merging with existing game progress.");
         MergeWith(progress);
     }
 
     //load save from cloud
     public void LoadFromCloud(){
         Debug.Log("Loading game progress from the cloud.");
         m_saving = false;
         ((PlayGamesPlatform)Social.Active).SavedGame.OpenWithAutomaticConflictResolution(
             m_saveName, //name of file.
             DataSource.ReadCacheOrNetwork,
             ConflictResolutionStrategy.UseLongestPlaytime,
             SavedGameOpened);
     }
 
     //overwrites old file or saves a new one
     public void SaveToCloud() {
         if (Authenticated) {
             Debug.Log("Saving progress to the cloud... filename: " + m_saveName);
             m_saving = true;
             //save to named file
             ((PlayGamesPlatform)Social.Active).SavedGame.OpenWithAutomaticConflictResolution(
                 m_saveName, //name of file. If save doesn't exist it will be created with this name
                 DataSource.ReadCacheOrNetwork,
                 ConflictResolutionStrategy.UseLongestPlaytime,
                 SavedGameOpened);
         } else {
             Debug.Log("Not authenticated!");
         }
     }
 
     //save is opened, either save or load it.
     private void SavedGameOpened(SavedGameRequestStatus status, ISavedGameMetadata game) {
         //check success
         if (status == SavedGameRequestStatus.Success){
             //saving
             if (m_saving){
                 //read bytes from save
                 byte[] data = ToBytes();
                 //create builder. here you can add play time, time created etc for UI.
                 SavedGameMetadataUpdate.Builder builder = new SavedGameMetadataUpdate.Builder();
                 SavedGameMetadataUpdate updatedMetadata = builder.Build();
                 //saving to cloud
                 ((PlayGamesPlatform)Social.Active).SavedGame.CommitUpdate(game, updatedMetadata, data, SavedGameWritten);
             //loading
             } else {
                 ((PlayGamesPlatform)Social.Active).SavedGame.ReadBinaryData(game, SavedGameLoaded);
             }
         //error
         } else {
             Debug.LogWarning("Error opening game: " + status);
         }
     }
 
     //callback from SavedGameOpened. Check if loading result was successful or not.
     private void SavedGameLoaded(SavedGameRequestStatus status, byte[] data) {
         if (status == SavedGameRequestStatus.Success){
             Debug.Log("SaveGameLoaded, success=" + status);
             ProcessCloudData(data);
         } else {
             Debug.LogWarning("Error reading game: " + status);
         }
     }
 
     //callback from SavedGameOpened. Check if saving result was successful or not.
     private void SavedGameWritten(SavedGameRequestStatus status, ISavedGameMetadata game) {
         if (status == SavedGameRequestStatus.Success){
             Debug.Log("Game " + game.Description + " written");
         } else {
             Debug.LogWarning("Error saving game: " + status);
         }
     }
 
     //merge local save with cloud save. Here is where you change the merging betweeen cloud and local save for your setup.
     private void MergeWith(string other) {
         if (other != "") {
             saveString = other;
         } else {
             Debug.Log("Loaded save string doesn't have any content");
         }
     }
 
     //return saveString as bytes
     private byte[] ToBytes() {
         byte[] bytes = Encoding.UTF8.GetBytes(saveString);
         return bytes;
     }
 
     //take bytes as arg and return string
     private string FromBytes(byte[] bytes) {
         string decodedString = Encoding.UTF8.GetString(bytes);
         return decodedString;
     }
 
     // -------------------- ### Extra UI for testing ### -------------------- 
 
     //call this with Unity button to view all saves on GPG. Bug: Can't close GPG window for some reason without restarting.
     public void showUI() {
         // user is ILocalUser from Social.LocalUser - will work when authenticated
         ShowSaveSystemUI(Social.localUser, (SelectUIStatus status, ISavedGameMetadata game) => {
             // do whatever you need with save bundle
         });
     }
     //displays savefiles in the cloud. This will only include one savefile if the m_saveName hasn't been changed
     private void ShowSaveSystemUI(ILocalUser user, Action<SelectUIStatus, ISavedGameMetadata> callback) {
         uint maxNumToDisplay = 3;
         bool allowCreateNew = true;
         bool allowDelete = true;
 
         ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
 
         if (savedGameClient != null) {
             savedGameClient.ShowSelectSavedGameUI(user.userName + "\u0027s saves",
                 maxNumToDisplay,
                 allowCreateNew,
                 allowDelete,
                 (SelectUIStatus status, ISavedGameMetadata saveGame) => {
                     // some error occured, just show window again
                     if (status != SelectUIStatus.SavedGameSelected) {
                         ShowSaveSystemUI(user, callback);
                         return;
                     }
 
                     if (callback != null)
                         callback.Invoke(status, saveGame);
                 });
         } else {
             // this is usually due to incorrect APP ID
             Debug.LogError("Save Game client is null...");
         }
     }
 
 }
 #endif 

......................

我遇到了同樣的問題,這是因為我通過 R8 勾選了 minify,刪除了勾選解決了我的問題,我再次對其進行了測試,啟用 R8 minify 只是給了我你所擁有的確切例外。

此選項位於player settingsother settings下拉列表的末尾,此異常僅在禁用Developement Build時發生

確保 function header 與Call()CallStatic()方法匹配。 如果您的方法接受任何 arguments 那么您必須創建一個參數數組並將其傳遞給Call()方法。 否則它將通過提到的錯誤。

假設您有一個 [ICODE]PrintString[/ICODE] 方法,它接受兩個 arguments。

public void PrintString(Context context, final String message )
{
    //create/show an android toast, with the message and short duration.
    new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
        }
    });
}

然后你必須像這樣調用 Unity 應用程序中的方法,

 public void ShowToast(string msg) {
    if (Application.platform == RuntimePlatform.Android) {
        // Retrieve the UnityPlayer class.
        AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");

        // Retrieve the UnityPlayerActivity object ( a.k.a. the current context )
        AndroidJavaObject unityActivity = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");

        // Retrieve the "Bridge" from our native plugin.
        // ! Notice we define the complete package name.             
        AndroidJavaObject alert = new AndroidJavaObject("com.codemaker.mylibrary.Alert");

        // Setup the parameters we want to send to our native plugin.             
        object[] parameters = new object[2];
        parameters[0] = unityActivity;
        parameters[1] = msg;

        // Call PrintString in bridge, with our parameters.
        alert.Call("PrintString", parameters);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM