您的位置:首页 > 移动开发 > Unity3D

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

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

  因为项目的上一上线版本是由Unity5.3发的包,而最新的项目来不及同步更新到5.3版本发包测试,所以只好仍然使用老的Unity版本4.3进行发包,然后,问题来了:PlayerPrefs的存储方式变了,新版本Unity5向下兼容Unity4,但是想再回来的时候,数据没办法了。
  先说一下Android平台上apk的数据存储位置(针对Unity4的版本):
安装在内置的flash存储器上的时候,PlayerPrefs的数据存储位置是\data\data\com.company.product\shared_prefs\com.company.product.xml
安装在内置的SD卡存储器上的时候,PlayerPrefs的存储位置是\sdcard\Android\data\com.company.product\shared_prefs\com.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_USER\Software\[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通信的一种封装。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: