5

重複の可能性:
JSON解析の問題

JSONファイルを解析しています(これは有効です)。Android 4.0-4.0.4で動作しますが、古いAndroidバージョンでは動作しません。これは私のマニフェストの一部です:

<uses-sdk
    android:minSdkVersion="7"
    android:targetSdkVersion="14" />

そして、これは私の解析コードです:

public JSONObject getJSONFromUrl(String url) {
    try {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);

        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        is = httpEntity.getContent();

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                is, "UTF-8"), 8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        is.close();
        json = sb.toString();
    } catch (Exception e) {
        Log.e("Buffer Error", "Error converting result " + e.toString());
    }

    try {
        jObj = new JSONObject(json);
    } catch (JSONException e) {
        Log.e("JSON Parser", "Error parsing data " + e.toString());
    }

    return jObj;

}

また、古いデバイスでは、次のエラーメッセージが表示されます(ただし、新しいAndroidデバイスではそうではありません)。

org.json.JSONException:タイプjava.lang.Stringの値をJSONObjectに変換できません

なぜAndroid4で動作するのか、古いデバイスでは動作しないのか、まったくわかりません。

ここからJsonを見つけます

4

12 に答える 12

3

JSONObject新しい Android リリースでは、パーサーがより寛大になっている可能性があります。あなたが得ているエラーメッセージは、特に受信側で疑わしい正当なJSONが原因のようです:

ダウンロードした JSON をファイルに書き出し、オリジナルと比較して、ダウンロード ロジックに問題があるかどうかを確認することをお勧めします。


アップデート

問題を再現できません。Android 4.0.3、2.3.3、2.2、および 2.1 では、次のアクティビティを使用して外部ストレージから JSON を完全に正常にロードできます (注: 私は怠け者で、外部ストレージへのパスに配線されていました)。

package com.commonsware.jsontest;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import org.json.JSONException;
import org.json.JSONObject;

public class JSONTestActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    try {
      BufferedReader in=
          new BufferedReader(new FileReader("/mnt/sdcard/test.json"));
      String str;
      StringBuilder buf=new StringBuilder();

      while ((str=in.readLine()) != null) {
        buf.append(str);
        buf.append("\n");
      }

      in.close();
      JSONObject json=new JSONObject(buf.toString());

      ((TextView)findViewById(R.id.stuff)).setText(json.toString());
    }
    catch (IOException e) {
      Log.e(getClass().getSimpleName(), "Exception loading file", e);
    }
    catch (JSONException e) {
      Log.e(getClass().getSimpleName(), "Exception parsing file", e);
    }
  }
}
于 2012-06-18T15:27:54.863 に答える
2

こんにちは私は次のコードを使用しましたが、2.2ではエラーは発生しませんでした。2.3.3コードは非常に単純です。

import java.io.IOException;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class NannuExpActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        try {
            JSONObject jo = getJSONObjectFromUrl("http://pastebin.com/raw.php?i=Jp6Z2wmX");
            for(int i=0;i<jo.getJSONArray("map_locations").length();i++)
            Log.d("Data",jo.getJSONArray("map_locations").getJSONObject(i).getString("title"));
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

    public JSONObject getJSONObjectFromUrl(String url) throws ClientProtocolException, IOException, JSONException{
        JSONObject jobj = null;
        HttpClient hc = new DefaultHttpClient();
        HttpGet hGet = new HttpGet(url);
        ResponseHandler<String> rHand = new BasicResponseHandler();
        String resp = "";
        resp = hc.execute(hGet,rHand);
        jobj = new JSONObject(resp);    
        return jobj;
    }
}

それが役に立てば幸い。

于 2012-06-21T17:13:48.793 に答える
2

ここでの解決策は、サーバーから返される utf-8 エンコーディングが原因である問題を解決します。

JSON 解析の問題

于 2012-10-08T04:10:53.337 に答える
2

私はjsonに次のコードを使用しました。私にとっては、すべてのAndroidバージョンをサポートしています。

List<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("data", qry));
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters);

HttpPost request = new HttpPost(your url);
request.setEntity(formEntity);

HttpResponse rp = hc.execute(request);
Log.d("UkootLog", "Http status code " + rp.getStatusLine().getStatusCode());

if (rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK
    || rp.getStatusLine().getStatusCode() >= 600) {
  Log.d("JsonLog", "Success !!");
  String result = EntityUtils.toString(rp.getEntity());
} else {
  Log.d("UkootLog", "Failed while request json !!");
}

これがお役に立てば幸いです。

于 2012-06-22T12:36:00.313 に答える
2

通常、Android で Http 接続を介して json オブジェクトを作成するには、次の手順を実行します。

  1. 接続を開き、応答を取得します。
  2. コンテンツを取得し、文字列ビルダーを作成します。
  3. 文字列ビルダーをjson配列オブジェクトにします(このステップはまだ行っていません)
  4. json 配列オブジェクトから json オブジェクトを取得します。

String Buffer(sb) を json 配列オブジェクトに変換するのに失敗したと思います。その代わりに、文字列バッファーから json オブジェクトを直接作成します。Android 4.0でどのように機能したかわかりません。変更されたコードは

public JSONObject getJSONFromUrl(String url) {
    try {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);

        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        is = httpEntity.getContent();

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                is, "UTF-8"), 8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        is.close();
        json = sb.toString();
    } catch (Exception e) {
        Log.e("Buffer Error", "Error converting result " + e.toString());
    }

    try {
       JSONArray jObj = new JSONArray(json);
    } catch (JSONException e) {
        Log.e("JSON Parser", "Error parsing data " + e.toString());
    }

    return jObj;

}

そして、次のようなインデックス値を渡すことで json オブジェクトを取得できます。

jObj.getJSONObject(i); /*i is a integer, index value*/

于 2012-06-18T17:57:47.307 に答える
1

json次の行で呼び出される変数のタイプは何ですか。json = sb.toString();

文字列ですか?の場合は、JSONObjectタイプをに変更するStringと、コードは完全に機能します。


もう1つの注意点は、例外の処理です。文字列を作成するときに最初のブロックで例外がスローされた場合、JSONObjectいくつかの障害のあるデータを使用して初期化が試行されるようです。


とにかくこれを試してください(あなたのダウンロード方法はバグがあると思います):

public JSONObject getJSONFromUrl(String url) {
    try {
        HttpPost postMethod = new HttpPost(SERVER_URL);
        ResponseHandler<String> res = new BasicResponseHandler();
        ResponseHandler<String> res = new ResponseHandler<String>() {
            public String handleResponse(final HttpResponse response) throws HttpResponseException, IOException {
                StatusLine statusLine = response.getStatusLine();
                if (statusLine.getStatusCode() >= 300) {
                    throw new HttpResponseException(
                    statusLine.getStatusCode(),
                    statusLine.getReasonPhrase());
                }
                HttpEntity entity = response.getEntity();
                return entity == null ? null : EntityUtils.toString(entity, "UTF-8");
            }
        };

        String response = (new DefaultHttpClient()).execute(postMethod, res);
        return new JSONObject(json);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}
于 2012-06-25T09:23:11.087 に答える
1

このエラーが発生する理由がよくわかりません。しかし、私も同様の問題に遭遇し、charSet を変更することで解決しました。iso-8859-1の代わりに使ってみてくださいUTF-8

于 2012-06-19T08:03:43.887 に答える
1

ジャクソンかGSON。

そこにドイツ語の余分な文字があり、国際化 (i18n) または utf-8 の問題である可能性があります。

Eclipse を再起動し、クリーン ビルドを実行して、もう一度やり直します。

于 2012-06-22T02:41:54.940 に答える
1

コードをコピーし、メソッドへの入力としてhttp://pastebin.com/raw.php?i=Jp6Z2wmXを使用しました。getJSONFromUrl(String url)興味深いことに、私はあなたの問題を再現できませんでした (15、10、または 7 の AVD および/またはターゲット API のいくつかの組み合わせで)。

私が気づくいくつかのこと:

  • InputStream isString jsonJSONObject jObjはメソッドの外部で宣言されてgetJSONFromUrl()おり、ある API で実行すると、別の API と比較して、コードの他の部分によって何らかの影響を受ける可能性があります。

  • 取得した例外を見ると、コンストラクターStringへの入力JSONObjectが空の文字列 ("") であることが原因でスローされている可能性があります。どういうわけか、サーバーが古い Android に別のデータを提供した可能性はありますか?

ここに私の提案があります:

  • getJSONFromUrl()メソッドの先頭に次の行を追加します。

    InputStream is = null;
    String json = null;
    JSONObject jObj = null;
    
  • 次のように、最後の 2 つの try-catch ブロックの間にダウンロードされた文字列を出力するデバッグ コードの行を追加します。

    // ----- cut ----
        Log.e("Buffer Error", "Error converting result " + e.toString());
    }
    
    Log.d("getJSONFromUrl", "json=(" + json + ")");
    
    try {
        jObj = new JSONObject(json);
    // ----- cut ----
    

上記の変更のいずれかまたは両方を行った後、問題について詳しく知ることができると思います:)

于 2012-06-19T21:48:25.340 に答える
1

ジャクソンを試しましたか?Androidのすべてのバージョンで使用しましたが、非常にうまく機能します。

http://jackson.codehaus.org/

于 2012-06-19T15:41:09.790 に答える
1

JSONParser を試しましたか?

ここに私が使用する例があります:

   JSONObject json = new JSONObject();
   JSONParser jsonParser = new JSONParser(); 


    try {

        if(jsonString != null)
            json =  (JSONObject) jsonParser.parse(jsonString);

    } catch (ParseException e) {        
        e.printStackTrace();
    }
于 2012-06-19T15:45:53.263 に答える
0

確かにこれはうまくいくでしょう。Android バージョン 4.0 では、例外を回避するために asynctask を作成する必要がありNetworkOnMainThreadExceptionます。私にとってはうまくいきます。

public class Http_Get_JsonActivity extends Activity implements OnClickListener {


String d = new Date().toString();

private static final String TAG = "MyPost";

private boolean post_is_running = false;

private doSomethingDelayed doSth;

private String url = "http://192.168.1.1";
private InputStream is;
private String json;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);



    Button pushButton = (Button) findViewById(R.id.button1);
    pushButton.setOnClickListener(this);

}

@Override
protected void onPause() {
    super.onPause();
    if (post_is_running) { // stop async task if it's running if app gets
                            // paused
        Log.v(TAG, "Stopping Async Task onPause");
        doSth.cancel(true);
    }
}

@Override
protected void onResume() {
    super.onResume();
    if (post_is_running) {
        // start async task if it was running previously and was stopped by
        // onPause()
        Log.v(TAG, "Starting Async Task onResume");
        doSth = (doSomethingDelayed) new doSomethingDelayed().execute();
        // ((Button) findViewById(R.id.push_button)).setText("Resuming..");
    }
}

public void onClick(View v) {

    if (post_is_running == false) {
        post_is_running = true;
        Log.v(TAG, "Starting Async Task onClick");
        doSth = (doSomethingDelayed) new doSomethingDelayed().execute();

        // ((Button) findViewById(R.id.push_button)).setText("Starting..");
    } else {
        Log.v(TAG, "Stopping Async Task onClick");
        post_is_running = false;
        doSth.cancel(true);
        // ((Button) findViewById(R.id.push_button)).setText("Stopping..");
    }
}

private class doSomethingDelayed extends AsyncTask<Void, Integer, Void> {

    private int num_runs = 0;

    @Override
    protected Void doInBackground(Void... gurk) {

        // while (!this.isCancelled()) {
        Log.v(TAG, "going into postData");

        long ms_before = SystemClock.uptimeMillis();
        Log.v(TAG, "Time Now is " + ms_before);

        postData();

        Log.v(TAG, "coming out of postData");

        publishProgress(num_runs);

        return null;
    }

    @Override
    protected void onCancelled() {
        Context context = getApplicationContext();
        CharSequence text = "Cancelled BG-Thread";
        int duration = Toast.LENGTH_LONG;

        Toast.makeText(context, text, duration).show();

    }

    @Override
    protected void onProgressUpdate(Integer... num_runs) {
        Context context = getApplicationContext();
    }
}

/**
 * Method to send data to the server
 */

public void postData() {
    try {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet httpPost = new HttpGet(url);
        System.out.println("--httppost----" + httpPost);
        HttpResponse httpResponse = httpClient.execute(httpPost);
        System.out.println("--httpResponse----" + httpResponse);
        HttpEntity httpEntity = httpResponse.getEntity();
        System.out.println("--httpEntity----" + httpEntity);
        is = httpEntity.getContent();
        System.out.println("--is----" + is);

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                is, "UTF-8"), 8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        is.close();
        json = sb.toString();
    } catch (Exception e) {
        Log.e("Buffer Error", "Error converting result " + e.toString());
    }

    try {
        JSONArray jObj = new JSONArray(json);
        System.out.println("--jObjt--" + jObj);
    } catch (JSONException e) {
        Log.e("JSON Parser", "Error parsing data " + e.toString());
    }

}

}

楽しい..

于 2012-06-22T12:08:52.370 に答える