Unity4向上(Unity5)兼容PlayerPrefs的数据存储

  好久没有写项目、开发相关的内容了,刚好最近在做项目的更新时,遇到一个比较有意思的坑就随手记录一下。

  因为项目的上一上线版本是由Unity5.3发的包,而最新的项目来不及同步更新到5.3版本发包测试,所以只好仍然使用老的Unity版本4.3进行发包,然后,问题来了:PlayerPrefs的存储方式变了,新版本Unity5向下兼容Unity4,但是想再回来的时候,数据没办法了。
  先说一下Android平台上apk的数据存储位置(针对Unity4的版本):
安装在内置的flash存储器上的时候,PlayerPrefs的数据存储位置是datadatacom.company.productshared_prefscom.company.product.xml
安装在内置的SD卡存储器上的时候,PlayerPrefs的存储位置是sdcardAndroiddatacom.company.productshared_prefscom.company.product.xml
(查看及获取该文件需要权限)

  其中shared_prefs是SharedPreferences的缩写,是Android平台提供的一个轻量级存储类,可以保存应用的一些常用配置,比如Activity的状态等,Activity暂停时其状态就会保存到SharedPereferences中;当Activity重载时,系统回调方法onSaveInstanceState时,会再从SharedPreferences中将值取出。(SharedPreferences可以用来进行数据共享,包括应用程序之间、一个应用的不同组件之间等。eg:两个activity除了可以通过Intent传递数据,也可以通过ShreadPreferences来共享数据)。

而在升级到Unity5之后,底层数据的存储位置发生了变化,数据存储文件变成了com.company.product.v2.playerprefs.xml,并且数据的存储方式也有所改变,在Unity4的时候,PlayerPrefs会将数据直接进行存储,在Unity5中,数据存储时会先进行一步Url编码,比如key或value值中含有“=”号的,在存储时会被编码为%3D,因此,要做到Unity4的向上兼容,数据的编码解码也要考虑进去。下面直接上代码:
Ps:是否安装到sd卡由PlayerSetting->Other Settings->Install Location的设置决定;在Windows平台下,PlayerPrefs被存储在注册表的HKEY_CURRENT_USERSoftware[company name][product name]中,company和product名由Project Setting的设置决定。

java端简化逻辑:

  1 public class UnityPlayerClient extends UnityPlayerActivity
  2 {
  3   protected static final String TAG = "UnityPlayerClient";
  4 
  5   @Override
  6   protected void onCreate(Bundle savedInstanceState) 
  7   {
  8     super.onCreate(savedInstanceState);
  9   }
 10 
 11 //    protected SharedPreferences curPlayerPrefs = null;
 12 //    public SharedPreferences CurPlayerPrefs()
 13 //    {
 14 //    if(null == curPlayerPrefs)
 15 //    {
 16 //    curPlayerPrefs = this.getSharedPreferences(this.getPackageName() + ".v2.playerprefs", Context.MODE_PRIVATE);
 17 //    }
 18 //    return curPlayerPrefs;
 19 //    }
 20 
 21   protected static boolean isUnityVersionNew = false;
 22   protected static SharedPreferences playerPrefs = null;
 23   public static SharedPreferences PlayerPrefs()
 24   {
 25     if(null == playerPrefs)
 26     {
 27       Context tAppContext = UnityPlayer.currentActivity.getApplicationContext();
 28       String tPath = "/data/data/" + tAppContext.getPackageName() + "/shared_prefs/" + tAppContext.getPackageName() + ".v2.playerprefs.xml";
 29       File tFile = new File(tPath);
 30       if(tFile.exists())
 31       {
 32         isUnityVersionNew = true;
 33         playerPrefs = tAppContext.getSharedPreferences(tAppContext.getPackageName() + ".v2.playerprefs", Context.MODE_PRIVATE);
 34       }
 35       else
 36       {
 37         isUnityVersionNew = false;
 38         playerPrefs = tAppContext.getSharedPreferences(tAppContext.getPackageName(), Context.MODE_PRIVATE);
 39       }
 40     }
 41     return playerPrefs;
 42   }
 43   private static String handleKey(String _key) 
 44   {
 45     try 
 46     {
 47       _key = isUnityVersionNew ? URLEncoder.encode(_key, "utf-8") : _key;
 48     } 
 49     catch (Exception e) 
 50     {
 51 
 52     }
 53     return _key;
 54   }
 55   private static String handleValue(String _value) 
 56   {
 57     try 
 58     {
 59       _value = isUnityVersionNew ? URLDecoder.decode(_value, "utf-8") : _value;
 60     } 
 61     catch (Exception e) 
 62     {
 63 
 64     }
 65     return _value;
 66   }
 67   public static String GetString(String _key)
 68   {
 69     return handleValue(PlayerPrefs().getString(handleKey(_key), ""));
 70   }
 71   public static String GetString(String _key, String _defaultValue)
 72   {
 73     return handleValue(PlayerPrefs().getString(handleKey(_key), _defaultValue));
 74   }
 75   public static boolean SetString(String _key, String _value)
 76   {
 77     return PlayerPrefs().edit().putString(handleKey(_key), handleKey(_value)).commit();
 78   }
 79 
 80   public static int GetInt(String _key)
 81   {
 82     return PlayerPrefs().getInt(handleKey(_key), 0);
 83   }
 84   public static int GetInt(String _key, int _defaultValue)
 85   {
 86     return PlayerPrefs().getInt(handleKey(_key), _defaultValue);
 87   }
 88   public static boolean SetInt(String _key, int _value)
 89   {
 90     return PlayerPrefs().edit().putInt(handleKey(_key), _value).commit();
 91   }
 92 
 93   public static float GetFloat(String _key)
 94   {
 95     return PlayerPrefs().getFloat(handleKey(_key), 0);
 96   }
 97   public static float GetFloat(String _key, float _defaultValue)
 98   {
 99     return PlayerPrefs().getFloat(handleKey(_key), _defaultValue);
100   }
101   public static boolean SetFloat(String _key, float _value)
102   {
103     return PlayerPrefs().edit().putFloat(handleKey(_key), _value).commit();
104   }
105 
106   public static boolean GetBool(String _key)
107   {
108     return PlayerPrefs().getBoolean(handleKey(_key), false);
109   }
110   public static boolean GetBool(String _key, boolean _defaultValue)
111   {
112     return PlayerPrefs().getBoolean(handleKey(_key), _defaultValue);
113   }
114   public static boolean SetBool(String _key, boolean _value)
115   {
116     return PlayerPrefs().edit().putBoolean(handleKey(_key), _value).commit();
117   }
118 
119   public static boolean HasKey(String _key)
120   {
121     return PlayerPrefs().contains(handleKey(_key));
122   }
123   public static boolean DeleteKey(String _key)
124   {
125     return PlayerPrefs().edit().remove(handleKey(_key)).commit();
126   }
127   public static boolean DeleteAll()
128   {
129     return PlayerPrefs().edit().clear().commit();
130   }
131 }

Unity端简化逻辑

  1 public class LocalInfoClient : IDataSave
  2 {
  3   private LocalInfoClient() { }    //泛型单件
  4 
  5   private IDataSave _curDataSave = null;
  6   protected IDataSave curDataSave
  7   {
  8     get
  9     {
 10       if(null == _curDataSave)
 11       {
 12 #if UNITY_EDITOR
 13         _curDataSave = new InfoWithoutEncry();
 14 #elif (UNITY_4_0 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9)
 15         if(true)    //从项目配置文件中读取
 16         {
 17           _curDataSave = new Info4UnityNew();
 18         }
 19         else
 20         {
 21           _curDataSave = new InfoBase();
 22         }
 23 #else
 24         _curDataSave = new InfoBase();
 25 #endif
 26       }
 27       return _curDataSave;
 28     }
 29   }
 30 
 31   public void SetInt(string _key, int _value)
 32   {
 33     curDataSave.SetInt(_key, _value);
 34   }
 35 
 36   public int GetInt(string _key, int _defaultValue)
 37   {
 38     return curDataSave.GetInt(_key, _defaultValue);
 39   }
 40 
 41   public void SetString(string _key, string _value)
 42   {
 43     curDataSave.SetString(_key, _value);
 44   }
 45 
 46   public string GetString(string _key, string _defaultValue)
 47   {
 48     return curDataSave.GetString(_key, _defaultValue);
 49   }
 50 
 51   public void SetFloat(string _key, float _value)
 52   {
 53     curDataSave.SetFloat(_key, _value);
 54   }
 55 
 56   public float GetFloat(string _key, float _defaultValue)
 57   {
 58     return curDataSave.GetFloat(_key, _defaultValue);
 59   }
 60 
 61   public bool HasKey(string _key)
 62   {
 63     return curDataSave.HasKey(_key);
 64   }
 65 
 66   public void DeleteKey(string _key)
 67   {
 68     curDataSave.DeleteKey(_key);
 69   }
 70 
 71   public void DeleteAll()
 72   {
 73     curDataSave.DeleteAll();
 74   }
 75 
 76   public void SetBool(string _key, bool _value)
 77   {
 78     curDataSave.SetBool(_key, _value);
 79   }
 80 
 81   public bool GetBool(string _key, bool _defaultValue)
 82   {
 83     return curDataSave.GetBool(_key, _defaultValue);
 84   }
 85 }
 86 
 87 
 88 public interface IDataSave
 89 {
 90   void SetInt(string _key, int _value);
 91   int GetInt(string _key, int _defaultValue);
 92 
 93   void SetString(string _key, string _value);
 94   string GetString(string _key, string _defaultValue);
 95 
 96   void SetFloat(string _key, float _value);
 97   float GetFloat(string _key, float _defaultValue);
 98 
 99   bool HasKey(string _key);
100   void DeleteKey(string _key);    
101   void DeleteAll();
102 
103   void SetBool(string _key, bool _value);
104   bool GetBool(string _key, bool _defaultValue);
105 }

其中Info4UnityNew类为实现了IDataSave接口并负责与java端UnityPlayerClient通信的一种封装。

原文地址:https://www.cnblogs.com/wayland/p/6206724.html