我正在尝试将我的播放器数组保存到JSONArray
,将其转换为字符串,将其放入SharedPreferences
然后将其转换回来。如果我尝试访问阵列中的任何Player实例,那么当我使用当前尝试重新加载应用程序时,JSONArray
正在返回运行异常/ ClassCast异常。
我哪里错了?
JSONArray savedPlayers;
SharedPreferences prefs;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.indie);
savedPlayers = new JSONArray();
prefs = getSharedPreferences("appData", 0);
String jsonString = prefs.getString("playerString", null);
//Restores playerArray if any players have been saved in the past
if(jsonString != null)
{
try
{
savedPlayers = new JSONArray(JSONString);
MyListView.players.clear();
MyListView.ids.clear();
for(int i = 0; i < savedPlayers.length(); i++)
{
MyListView.players.add(((Player) savedPlayers.get(i)).getName()); //Error
MyListView.ids.add(((Player) savedPlayers.get(i)).getSaveId());
}
}
catch (JSONException e)
{
e.printStackTrace();
}
}
}
//If there are savedPlayers converts the JSONArray to a string and saved it within SharedPreferences
@Override
protected void onPause()
{
if(savedPlayers != null)
{
SharedPreferences.Editor editor = getSharedPreferences("appData", 0).edit();
String jsonString = savedPlayers.toString();
editor.putString("playerString", jsonString).commit();
}
super.onPause();
}
JSONString:
["en.deco.android.livehud.Player@44eba878","en.deco.android.livehud.Player@44ebec68"]
logcat的:
04-16 22:31:13.765: ERROR/AndroidRuntime(7496): Uncaught handler: thread main exiting due to uncaught exception
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): java.lang.RuntimeException: Unable to start activity ComponentInfo{en.deco.android.livehud/en.deco.android.livehud.GUI}: java.lang.ClassCastException: java.lang.String
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): at android.app.ActivityThread.access$2200(ActivityThread.java:119)
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): at android.os.Handler.dispatchMessage(Handler.java:99)
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): at android.os.Looper.loop(Looper.java:123)
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): at android.app.ActivityThread.main(ActivityThread.java:4363)
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): at java.lang.reflect.Method.invokeNative(Native Method)
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): at java.lang.reflect.Method.invoke(Method.java:521)
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): at dalvik.system.NativeStart.main(Native Method)
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): Caused by: java.lang.ClassCastException: java.lang.String
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): at en.deco.android.livehud.GUI.onCreate(GUI.java:102)
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
04-16 22:31:13.785: ERROR/AndroidRuntime(7496): ... 11 more
04-16 22:32:57.775: ERROR/AndroidRuntime(7537): Uncaught handler: thread main exiting due to uncaught exception
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): java.lang.RuntimeException: Unable to start activity ComponentInfo{en.deco.android.livehud/en.deco.android.livehud.GUI}: java.lang.ClassCastException: java.lang.String
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): at android.app.ActivityThread.access$2200(ActivityThread.java:119)
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): at android.os.Handler.dispatchMessage(Handler.java:99)
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): at android.os.Looper.loop(Looper.java:123)
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): at android.app.ActivityThread.main(ActivityThread.java:4363)
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): at java.lang.reflect.Method.invokeNative(Native Method)
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): at java.lang.reflect.Method.invoke(Method.java:521)
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): at dalvik.system.NativeStart.main(Native Method)
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): Caused by: java.lang.ClassCastException: java.lang.String
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): at en.deco.android.livehud.GUI.onCreate(GUI.java:102)
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
04-16 22:32:57.795: ERROR/AndroidRuntime(7537): ... 11 more
答案 0 :(得分:2)
您当前正在使用每个Player对象的toString表示创建一个JSONArray,这会产生一个字符串数组,这些字符串不包含来自Player本身字段的任何信息。如果您要使用JSONArray / JSONObject类,则需要为每个玩家创建一个JSONObject对象,并将其添加到JSONArray中。例如,以下代码将创建一个JSONObject,将该播放器的名称添加到该对象,然后将其添加到JSONArray:
JSONObject playerJsonObject = new JSONObject();
playerJsonObject.put("name", player.getName());
jsonArray.put(playerJsonObject);
然而,更简单的JSON序列化方法是使用GSON: http://code.google.com/p/google-gson/
答案 1 :(得分:1)
您应该考虑使用Jackson。
所有序列化和反序列化代码都将消失,您的生活将变得更加简单。
答案 2 :(得分:1)
String jsonString = savedPlayers.toString();
这不起作用。它在数组中的每个对象(Player)上调用toString。数组中的对象没有覆盖toString方法,因此只返回它们所在的内存空间:
en.deco.android.livehud.Player@44eba878
你需要在你的Player类中覆盖toString,我不知道你的类看起来像什么,但它会像这样:
public class Player {
String name;
int saveId;
public Player(String name, int saveId){
this.name = name;
this.saveId = saveId;
}
public String getName(){
return name;
}
public int getSaveId(){
return saveId();
}
@Override
public String toString(){
return "{" + "name:"+ this.name +"," + "saveId:"+ this.saveId +"}";
}
}
查看JSON站点以获取JSON应该是的结构的参考:http://www.json.org/
建议您在覆盖toString();
时覆盖hashcode()答案 3 :(得分:0)
你不应该首先将你的字符串转换为数组,然后解析为json数组吗?
答案 4 :(得分:0)
本机android JSON库对于在尝试编译不合适的类型时出现的错误类型非常敏感。因此,添加到您的每个调用JSON对象必须具有错误处理程序。
这导致了很多代码和复杂性,应该是一个真正无痛的过程。幸运的是,有些库可以让这种转换变得非常简单。我个人推荐GSON库: http://code.google.com/p/google-gson/
JSON可以轻松地将数据往返,将JSON对象序列化和反序列化为应用程序使用的Java类。
通读使用情况页面,您可以在4行代码中完成转换。 https://sites.google.com/site/gson/gson-user-guide#TOC-Serializing-and-Deserializing-Generic-Types
另外,@ Kamal提出了一个关于在java中首先将字符串转换为数组的要点。或者,或者使用GSON,您可以从自定义类类型转换它。它真的很容易。
答案 5 :(得分:0)
答案 6 :(得分:0)
我们需要先制作JSON对象。例如,如果resp是一个String(例如作为http响应出现)
JSONObject jsonObject = new JSONObject(resp);
jsonObject可能包含其他JSON对象或JSON数组。如何转换JSON取决于响应。 如果arraykey是JSON对象中的数组,那么我们可以通过以下方式获取数组列表。
JSONArray arr = jsonObject.getJSONArray("arraykey");
检查arr的长度,如果它大于0则根据数据包含JSON对象或JSON数组。 有一个完整的例子,可以找到关于JSON字符串到JSON数组的一些解释 http://www.hemelix.com/JSONHandling