1

プレーヤーの配列を に保存し、JSONArrayそれを文字列に変換し、配置してSharedPreferencesから元に戻そうとしています。配列内のJSONArrayPlayer インスタンスのいずれかにアクセスしようとすると、現在の試行でアプリをリロードすると、ランタイム例外/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
 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() をオーバーライドすることもお勧めします。

于 2012-04-17T12:07:58.547 に答える
1

これにはJacksonの使用を検討する必要があります。

シリアライゼーションとデシリアライゼーションのコードはすべてなくなり、人生はずっとシンプルになります。

于 2012-04-16T22:57:14.617 に答える
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配列として解析するべきではありませんか?

于 2012-04-16T22:23:30.427 に答える
0

最初に JSON オブジェクトを作成する必要があります。たとえば、resp が文字列の場合 (たとえば、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にあります。

于 2014-05-06T12:06:40.223 に答える