1

我需要一些关于处理 JSON 数据的建议。我已经得出一个绝对的结论,即我用于博客的 JSON 数据有问题。

我将 JSON 数据输入到一个 android 应用程序中,以在应用程序上显示信息。我遇到的问题是,当我使用我的 JSON 数据时,我得到了一个negativearraysize 异常。

现在在你责怪代码之前,请知道我使用 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();
    }
}

}

这是日志猫:

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)
4

2 回答 2

0

您的内容长度为负数(即未知)

看看这个以获得一些见解

https://stackoverflow.com/a/5428670/770467

希望能帮助到你

于 2013-08-01T02:08:38.287 回答
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();
       }
     }
于 2013-08-01T02:19:43.827 回答