JSON和内存问题

时间:2014-07-18 13:21:39

标签: java android json

我正在尝试将大量数据从网络加载到我的Android应用程序中,我一直收到此错误:

07-18 10:16:00.575: E/AndroidRuntime(30117): java.lang.OutOfMemoryError: [memory exhausted]

已经阅读了很多关于JSON的内容。我找到了一些解决方案,但没有什么真正帮助我。

这是我的代码:

public class HistoricoAdapter extends BaseAdapter {
    private Context ctx;
    JSONArray jsonArray;

    public HistoricoAdapter(Context ctx) {
        this.ctx = ctx;

        String readHttp = readHttp();

        try {
            // transforma a string retornada pela função readHttp() em array
            jsonArray = new JSONArray(readHttp);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public String readHttp() {

        // Acessa a URL que retorna uma string com  os dados do banco
        StringBuilder builder = new StringBuilder();
        HttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet("some url");
        try {
            HttpResponse response = client.execute(httpGet);
            StatusLine statusLine = response.getStatusLine();

            int statusCode = statusLine.getStatusCode();
            if (statusCode == 200) {
                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(content));
                String line;
                while ((line = reader.readLine()) != null) {
                    builder.append(line);
                }
            } else {
                Log.e(this.toString(), "Erro ao ler JSON!");
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return builder.toString();
    }

    public int getCount() {
        return jsonArray.length();
    }
    public boolean isEmpty(){

        if(jsonArray.toString().isEmpty()){
            return true;
        }
        else {
            return false;
        }
    }

    public Object getItem(int position) {
        JSONObject ob = null;
        try {
            ob = jsonArray.getJSONObject(position);
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return ob;
    }

    public long getItemId(int arg0) {
        return 0;
    }

    public View getView(int position, View view, ViewGroup arg2) {

        LayoutInflater layout = (LayoutInflater) ctx
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View v = layout.inflate(R.layout.listar_compromisso, null);

        try {
            JSONObject obj = (JSONObject) getItem(position);



        } catch (Exception ex) {

        }

        return v;
    }
}

任何人都可以预测为什么我会收到此错误?

2 个答案:

答案 0 :(得分:2)

如果您收到此错误,则JSON必须太大而无法缓冲到内存中。

问题是org.json太基本无法处理。

您需要一个高级库来传输响应,例如 GSON Jackson

答案 1 :(得分:0)

此代码存在一些问题。我注意到的第一件事是你没有在asynctask中调用你的web请求。您希望将async task用于所有长时间运行的操作,并且必须将其用于Web调用。

AsyncTask必须是子类才能使用。子类将覆盖至少一个方法(doInBackground(Params ...),并且通常会覆盖第二个方法

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
 protected Long doInBackground(URL... urls) {
     int count = urls.length;
     long totalSize = 0;
     for (int i = 0; i < count; i++) {
         totalSize += Downloader.downloadFile(urls[i]);
         publishProgress((int) ((i / (float) count) * 100));
         // Escape early if cancel() is called
         if (isCancelled()) break;
     }
     return totalSize;
 }

 protected void onProgressUpdate(Integer... progress) {
     setProgressPercent(progress[0]);
 }

 protected void onPostExecute(Long result) {
     showDialog("Downloaded " + result + " bytes");
 }
}

您还应该使用JSON来构建对象对象。它已经过测试,您可以在此文档中找到有关对象可以处理的信息。以下是该网站的一些信息:

Gson性能和可伸缩性

以下是我们在桌面(双opteron,8GB RAM,64位Ubuntu)上运行的一些指标,这些指标与测试一起运行了许多其他内容。您可以使用PerformanceTest类重新运行这些测试。 字符串:超过25MB的反序列化字符串没有任何问题(请参阅PerformanceTest中的disabled_testStringDeserializationPerformance方法) 大集合: 序列化了140万个对象的集合(请参阅PerformanceTest中的disabled_testLargeCollectionSerialization方法) 反序列化了87,000个对象的集合(请参阅PerformanceTest中的disabled_testLargeCollectionDeserialization) Gson 1.4将字节数组和集合的反序列化限制从80KB增加到11MB以上。

另外,使用Json到Java对象转换来构建类对象,就像那里one一样。如果这个链接稍后没有结束,还有更多。进行简单的Google搜索。

从json转换为Java Objects,但您也可以转换为自己的自定义对象。

Gson gson = new Gson();
int[] ints = {1, 2, 3, 4, 5};
String[] strings = {"abc", "def", "ghi"};

(Serialization)
gson.toJson(ints);     ==> prints [1,2,3,4,5]
gson.toJson(strings);  ==> prints ["abc", "def", "ghi"]