OutOfMemoryException异常大解析JSON响应时异常、OutOfMemoryException、JSON

2023-09-05 09:50:59 作者:小呀么小可爱

我在做一个项目,我需要通过的HttpClient 来解析从URL的JSON。我的code正常工作与少量的数据的JSON对象响应。但是,当我用同样的code,以得到一个庞大的数据量(超过3MB),我有一个问题,响应

I am doing a project where I need to parse JSON from a URL through HttpClient. My code works fine for JSON object responses with a small amount of data. But when I use the same code to get a response with a huge amount of data (more than 3MB), I have a problem.

下面是我的code:

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
//import java.util.HashMap;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
//import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
//import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;
import android.widget.Toast;

@SuppressWarnings("unused")
public class JSONfunctions {

    public static JSONObject getJSONfromURL(String url){
        InputStream is = null;
        String result = "";
        JSONObject jArray = null;

        //http post
        try{
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(url);
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();

        }catch(Exception e){
                Log.e("log_tag", "Error in http connection "+e.toString());
        }

        //convert response to string
        try{
                BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                        sb.append(line + "\n");
                }
                is.close();
                result=sb.toString();

            //    Toast.makeText(getBaseContext, result, Toast.LENGTH_LONG).

        }catch(Exception e){
                Log.e("log_tag", "Error converting result "+e.toString());
        }

        try{

            jArray = new JSONObject(result);            
        }catch(JSONException e){
                Log.e("log_tag", "Error parsing data "+e.toString());
        }

        return jArray;
    }
}

ListJson.java

import java.util.ArrayList;
import java.util.HashMap;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
//import org.w3c.dom.Document;
//import org.w3c.dom.Element;
//import org.w3c.dom.NodeList;



import android.app.ListActivity;
import android.content.Intent;
//import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;


public class ListJson extends ListActivity {
     public static JSONObject json;
     public static JSONArray data;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list1);

        ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
     //   String semail = "partha@excoflare.com";
      //  String spassword = "partha123";


      //  Toast.makeText(getApplicationContext(), JSONExample2.strEmail, Toast.LENGTH_LONG).show();
        //Toast.makeText(getApplicationContext(), JSONExample2.strPwd, Toast.LENGTH_LONG).show();

        //    

        json = JSONfunctions.getJSONfromURL("url here");      


            try{

            data = json.getJSONArray("server_list");


            for(int i=0;i<data.length();i++){                       
                HashMap<String, String> map = new HashMap<String, String>();    
                JSONObject e = data.getJSONObject(i);

                map.put("id", String.valueOf(i));
                map.put("name", "" + e.getString("ServUser"));
                map.put("email", "" + e.getString("ServURL"));
                mylist.add(map);
            }       
        }catch(JSONException e)        {
             Log.e("log_tag", "Error parsing data "+e.toString());
        }


//        try {
//          JSONObject newObject=json.getJSONObject("subscription");
//          JSONArray data1 = newObject.getJSONArray("cust_product");
//          
//          Toast.makeText(getApplicationContext(), data1.toString(), Toast.LENGTH_LONG).show();
//         
//          for(int i=0;i<data1.length();i++){                      
//                  HashMap<String, String> map1 = new HashMap<String, String>();   
//                  JSONObject e = data.getJSONObject(i);
//                  
//                  map1.put("id", String.valueOf(i));
//                  map1.put("name", "" + e.getString("ServUser"));
//                  map1.put("email", "" + e.getString("ServURL"));
//                  mylist.add(map1);
//              }       
//          
//      } catch (JSONException e) {
//          // TODO Auto-generated catch block
//          e.printStackTrace();
//      }


         ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.item_list,
                                  new String[] { "name", "email" }, 
                              new int[] { R.id.item_title, R.id.item_subtitle });
                                  setListAdapter(adapter);


      final ListView lv = getListView();
       lv.setTextFilterEnabled(true);   
        lv.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {              
                //@SuppressWarnings("unchecked")
                //HashMap<String, String> o = (HashMap<String, String>) lv.getItemAtPosition(position);                 
            //  Toast.makeText(ListJson.this, "ID '" + o.get("id") + "' was clicked.", Toast.LENGTH_SHORT).show(); 

                Toast.makeText(getApplicationContext(), parent.getItemAtPosition(position).toString(),
                        Toast.LENGTH_LONG).show();

            //   String a= parent.getItemAtPosition(position).toString();

                Intent intent2= new Intent(ListJson.this, ListJson2.class);
                 startActivity(intent2);
            }
        }); 

    }

我正在一个 OutOfMemoryException异常。我改变heap_size为192MB和RAM大小为32MB,但没有运气。我该如何解决这个问题?

I am getting an OutOfMemoryException. I changed heap_size to 192MB and ram size to 32MB, but with no luck. How can I fix this?

推荐答案

JSON的大数据量必须削减到更小的碎片。比如你有一个50000的产品在你的数据库。然后,它是明智的分页API请求 - 获得这笔巨额的产品由100-500记录上一个查询。这将解决您的问题。

Big amounts of data of JSON must be cut to smaller pieces. For example you have a 50000 products on your database. Then it's wise to paginate API requests - get this huge amount of products by 100-500 records on one query. That will solve your problem.

这个方法解决了一个问题更多 - 引起互联网和GPRS连接丢失错误等

This approach solves one problem more - errors caused by internet and gprs connection loss etc.

如果API是你的,那么你可以改变这一点。如果不是,那么这是API设计的一大失败,你可以发送更改请求。

If API is yours then you can change this. If not, then this is a big failure of API design and you can send change request.

编辑:

做了一点阅读和发现,强烈建议解析巨大的JSON数据加载 HTTP://jackson.$c$ chaus.org/ 。还没有尝试过,所以无法评论这个库。同时建议您保存此JSON流到文件(不加载到内存中),然后用大块分析它。

Did a little reading and found that highly recommended for parsing huge load of JSON data is http://jackson.codehaus.org/. Haven't tried it, so cannot comment about this library. Also recommend you to save this JSON stream into the file (don't load it to memory) and then parse it by chunks.

 
精彩推荐
图片推荐