1

我正在尝试将我的玩家数组保存为JSONArray,将其转换为字符串,将其放入SharedPreferences然后将其转换回来。如果JSONArray我尝试访问数组中的任何 Player 实例,我在使用当前尝试重新加载我的应用程序时会返回运行时异常/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();
}

JSON字符串:
["en.deco.android.livehud.Player@44eba878","en.deco.android.livehud.Player@44ebec68"]

日志猫:

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
4

7 回答 7

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/

于 2012-04-17T13:01:54.080 回答
1

您应该考虑为此使用杰克逊。

您所有的序列化和反序列化代码都将消失,您的生活将变得更加简单。

于 2012-04-16T22:57:14.617 回答
1
 String jsonString = savedPlayers.toString();

这是行不通的。它在数组中的每个对象(播放器)上调用 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();

于 2012-04-17T12:07:58.547 回答
0

您不应该先将字符串转换为 Array 然后解析为 json array 吗?

于 2012-04-16T22:23:30.427 回答
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,您可以将其从自定义类类型转换。它真的那么容易。

于 2012-04-16T23:06:22.447 回答
0

GSON 非常适合 JSON 操作:

这里回答了与您相同的问题:

无法将字符串转换为 JsonArray

于 2012-04-16T23:18:34.083 回答
0

我们需要先制作 JSON 对象。例如,如果 resp 是一个字符串(例如作为 http 响应)

JSONObject jsonObject = new JSONObject(resp); 

jsonObject 可能包含其他 JSON 对象或 JSON 数组。如何转换 JSON 取决于响应。如果 arraykey 是 JSON 对象中的一个数组,那么我们可以通过以下方式获取数组列表。

JSONArray arr  = jsonObject.getJSONArray("arraykey");

检查 arr 的长度,如果大于 0,则它包含 JSON 对象或 JSON 数组,具体取决于数据。可以在 http://www.hemelix.com/JSONHandling找到一个完整的示例,其中包含有关 JSON 字符串到 JSON 数组的一些解释

于 2014-05-06T12:06:40.223 回答