我需要一些关于操作JSON数据的建议。我得出一个绝对的结论,即我在博客中使用的JSON数据有问题。
我正在将JSON数据提供给Android应用程序以显示应用程序的信息。我遇到的问题是,当我使用我的JSON数据时,我得到了一个 消极的例外。
现在,在你责备代码之前,知道我使用teamtreehouse博客JSON代码在这里工作的应用程序正常工作:
http://blog.teamtreehouse.com/api/get_recent_summary/
所以这很好用。我让我的JSON代码看起来几乎与这段代码完全一样。数组嵌套相同,使用相同的命名约定......等等。
这是我的JSONcode,当它插入我的Android代码时会带回异常。
http://www.evotechmachine.com/api/get_recent_posts/?include=title,url,status,id,date
如果你比较两个JSON代码,你会发现它们在内部几乎相同。我在其中引用的唯一内容是帖子,标题和网址。我敢肯定它不是名字不匹配。我完全失去了。提前感谢人们。
public static final int NUMBER_OF_POSTS = 20;
public static final String TAG = MainListActivity.class.getSimpleName();
protected JSONObject mBlogData;
protected ProgressBar mProgressBar;
private final String KEY_TITLE = "title";
private final String KEY_AUTHOR = "author";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_list);
mProgressBar = (ProgressBar) findViewById(R.id.progressBar1);
if (isNetworkAvailable()) {
mProgressBar.setVisibility(View.VISIBLE);
GetBlogPostsTask getBlogPostsTask = new GetBlogPostsTask();
getBlogPostsTask.execute();
}
else {Toast.makeText(this, "network is unavailable", Toast.LENGTH_LONG).show();
}
// Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
JSONArray jsonPosts;
try {
jsonPosts = mBlogData.getJSONArray("posts");
JSONObject jsonPost = jsonPosts.getJSONObject(position);
String blogUrl = jsonPost.getString("url");
Intent intent = new Intent(this, BlogWebViewActivity.class);
intent.setData(Uri.parse(blogUrl));
startActivity(intent);
} catch (JSONException e) {
logException(e);
}
}
private void logException(Exception e) {
Log.e(TAG, "Exception caught!", e);
}
private boolean isNetworkAvailable() {
ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if (networkInfo != null && networkInfo.isConnected()) {
isAvailable = true;
}
return isAvailable;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void handleBlogResponse() {
mProgressBar.setVisibility(View.INVISIBLE);
if(mBlogData==null) {
updateDisplayForError();
}
else {
try {
JSONArray jsonPosts = mBlogData.getJSONArray("posts");
ArrayList<HashMap<String, String>> blogPosts =
new ArrayList<HashMap<String, String>>();
for (int i = 0;i< jsonPosts.length();i++) {
JSONObject post = jsonPosts.getJSONObject(i);
String title = post.getString(KEY_TITLE);
title = Html.fromHtml(title).toString();
String author = post.getString(KEY_AUTHOR);
author = Html.fromHtml(author).toString();
HashMap<String, String> blogPost = new HashMap<String, String>();
blogPost.put(KEY_TITLE, title);
blogPost.put(KEY_AUTHOR, author);
blogPosts.add(blogPost);
}
String[] keys= { KEY_TITLE, KEY_AUTHOR };
int[] ids = {android.R.id.text1, android.R.id.text2};
SimpleAdapter adapter = new SimpleAdapter(this, blogPosts, android.R.layout.simple_list_item_2, keys, ids);
setListAdapter(adapter);
} catch (JSONException e) {
logException(e);
}
}
}
private void updateDisplayForError() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.error_title));
builder.setMessage(getString(R.string.error_message));
builder.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.create();
dialog.show();
TextView emptyTextView = (TextView) getListView().getEmptyView();
emptyTextView.setText(getString(R.string.no_items));
}
private class GetBlogPostsTask extends AsyncTask<Object, Void, JSONObject> {
@Override
protected JSONObject doInBackground(Object... arg0) {
int responseCode = -1;
JSONObject jsonResponse = null;
try {
URL blogFeedUrl = new URL("http://www.evotechmachine.com/api/get_recent_posts/?include=title,url,status,id,date");
HttpURLConnection connection = (HttpURLConnection) blogFeedUrl.openConnection();
connection.connect();
responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK){
InputStream inputStream = connection.getInputStream();
Reader reader = new InputStreamReader(inputStream);
int contentLength = connection.getContentLength();
char[] charArray = new char[contentLength];
reader.read(charArray);
String responseData = new String(charArray);
jsonResponse = new JSONObject(responseData);
} else {
Log.i(TAG, "unsuccessful HTTP Response Code: " +responseCode);
}
Log.i(TAG, "Code: " + responseCode);
} catch (MalformedURLException e) {
logException(e);}
catch (IOException e) {
logException(e);
}
catch (Exception e) {
logException(e);
}
return jsonResponse;
}
@Override
protected void onPostExecute(JSONObject result) {
mBlogData = result;
handleBlogResponse();
}
}
}
这是logcat:
07-31 20:49:08.209: E/(32544): <s3dReadConfigFile:75>: Can't open file for reading
07-31 20:49:08.209: E/(32544): <s3dReadConfigFile:75>: Can't open file for reading
07-31 20:49:09.280: E/MainListActivity(32544): Exception caught!
07-31 20:49:09.280: E/MainListActivity(32544): java.lang.NegativeArraySizeException: -1
07-31 20:49:09.280: E/MainListActivity(32544): at com.nibbdigital.blogreader.MainListActivity$GetBlogPostsTask.doInBackground(MainListActivity.java:168)
07-31 20:49:09.280: E/MainListActivity(32544): at com.nibbdigital.blogreader.MainListActivity$GetBlogPostsTask.doInBackground(MainListActivity.java:1)
07-31 20:49:09.280: E/MainListActivity(32544): at android.os.AsyncTask$2.call(AsyncTask.java:287)
07-31 20:49:09.280: E/MainListActivity(32544): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
07-31 20:49:09.280: E/MainListActivity(32544): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
07-31 20:49:09.280: E/MainListActivity(32544): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
07-31 20:49:09.280: E/MainListActivity(32544): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
07-31 20:49:09.280: E/MainListActivity(32544): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
07-31 20:49:09.280: E/MainListActivity(32544): at java.lang.Thread.run(Thread.java:856)
答案 0 :(得分:0)
答案 1 :(得分:0)
int contentLength = connection.getContentLength(); 返回负长度
这是因为您的服务器未在http响应中设置content-length标头。两个解决方案: 1.您可以修复服务器端代码 2.您可以通过这种方式处理输入响应以转换为字符串:
BufferedReader br = null;
try
{
br = new BufferedReader(new InputStreamReader(inputStream);
StringBuilder sb = new StringBuilder();
for (String line; (line = br.readLine()) != null;) {
sb.append(line);
sb.append("\n");
}
return sb.toString();
}
finally
{
if (reader != null) {
reader.close();
}
}