可能重复:
JSON parsing problem
我正在解析一个JSON文件(哪个有效)。它适用于Android 4.0 - 4.0.4但不适用于较旧的Android版本。 这是我的Manifest的一部分:
<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
我完全不知道为什么它在Android 4上运行,但在旧设备上却无法运行。
从here
中找到Json答案 0 :(得分:3)
在较新的Android版本中,JSONObject
解析器可能更加宽松。您收到的错误消息似乎是由于可疑的合法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);
}
}
}
答案 1 :(得分:2)
通常这些是通过Android中的Http连接创建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*/
答案 2 :(得分: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;
}
}
希望它有所帮助。
答案 3 :(得分: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 !!");
}
我希望这会对你有所帮助。
答案 4 :(得分:2)
这里的解决方案将解决您的问题 这是因为从服务器返回的utf-8编码。
答案 5 :(得分:1)
我不太清楚你为什么会收到这个错误。但我也遇到过类似的问题,它通过更改charSet来解决。尝试使用iso-8859-1
代替UTF-8
。
答案 6 :(得分:1)
答案 7 :(得分:1)
您是否尝试过JSONParser?
这是我使用的一个例子:
JSONObject json = new JSONObject();
JSONParser jsonParser = new JSONParser();
try {
if(jsonString != null)
json = (JSONObject) jsonParser.parse(jsonString);
} catch (ParseException e) {
e.printStackTrace();
}
答案 8 :(得分:1)
我复制了您的代码并使用http://pastebin.com/raw.php?i=Jp6Z2wmX作为getJSONFromUrl(String url)
方法的输入。有趣的是,我无法重现您的问题(AVD和/或目标API的几种组合为15,10或7)。
我注意到的一些事情:
InputStream is
,String json
,JSONObject 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 ----
我认为在您做出上述一项或两项修改后,我们会更多地了解您的问题:)
答案 9 :(得分:1)
杰克逊或GSON。
可能是那里的德国额外角色和国际化(i18n)或utf-8问题。
我会重启Eclipse,做一个干净的构建并再试一次。
答案 10 :(得分:1)
行中json
json = sb.toString();
的变量的类型是什么
是字符串吗?如果是JSONObject
,请将其类型更改为String
,您的代码将完美运行。
另一个注意事项是处理异常:似乎如果在构建String时在第一个块中抛出异常,则会尝试使用某些错误数据进行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;
}
}
答案 11 :(得分:0)
当然这会奏效。在4.0 android版本中,我们必须创建asynctask以避免异常,即NetworkOnMainThreadException
ll get。它对我来说很好。
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());
}
}
}
享受..