【问题标题】:Android Http Post streaming jsonAndroid Http Post 流式传输 json
【发布时间】:2011-09-13 22:15:57
【问题描述】:

我在尝试使用 json (gson) 将 SQLite 数据发送到 Web 服务器时遇到了麻烦。 一切都很好,直到桌子大约有 6000 行。 我遇到了内存不足错误。

在我的数据助手中,我有:

public String DonneesToJson (SQLiteDatabase db, int chantier, int chantier_serveur )
{
    Cursor c = db.rawQuery("select * from "+P_TABLE+" where "+P_CHANTIER+"="+chantier+ " order by "+P_TIME+" desc ", null);

    List<Donnees> donnees = new ArrayList<Donnees>();
    c.moveToFirst();

    while (c.moveToNext())
    {
        Donnees d = new Donnees (
                c.getInt(c.getColumnIndex(Datahelper.P_ID)),
                chantier_serveur,
                offset,
                c.getInt(c.getColumnIndex(Datahelper.P_PLAN)),
                c.getString(c.getColumnIndex(Datahelper.P_TIME)),
                c.getInt(c.getColumnIndex(Datahelper.P_PRESSION)),
                c.getInt(c.getColumnIndex(Datahelper.P_PROFONDEUR)),
                c.getInt(c.getColumnIndex(Datahelper.P_PROFONDEUR_TOTALE)),
                c.getInt(c.getColumnIndex(Datahelper.P_ANGLE_X)),
                c.getInt(c.getColumnIndex(Datahelper.P_ANGLE_Y)),
                c.getString(c.getColumnIndex(Datahelper.P_PIEU)),
                c.getInt(c.getColumnIndex(Datahelper.P_NO_RALLONGE)),
                c.getString(c.getColumnIndex(Datahelper.P_RALLONGE)),
                c.getInt(c.getColumnIndex(Datahelper.P_MOTEUR)),
                c.getString(c.getColumnIndex(Datahelper.P_SERIE)),
                c.getDouble(c.getColumnIndex(Datahelper.P_COEFF_A)),
                c.getDouble(c.getColumnIndex(Datahelper.P_COEFF_B))
        );
        donnees.add(d);
    }

    c.close();

    Gson gson = new Gson();

    return gson.toJson(donnees);
}

基本上我是这样称呼的:

String resultat = dbHelper.DonneesToJson(db,i, chantier_serveur);

HttpPost post2 = new HttpPost("http://www.zzzzzzz.com/test.php");
StringEntity se = new StringEntity(resultat);  
se.setContentEncoding( new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post2.setEntity(se);
response = client.execute(post2);

在服务器端,将数据存储在一个大的 sql DB 中然后进行分析是非常基本的 php。

即: $decoded = json_decode($HTTP_RAW_POST_DATA,true); foreach ( $decoded as $key => $value) { $query = ...

在做 OOM 错误时,它很慢。我的意思是获取 sql 数据到 json 很慢。

我试图走杰克逊路线,更快,没有内存不足错误,但是......它只能写入文件或流。 我会尽量避免写入文件,然后通过 http post 发送文件。 所以我决定打开一个http流来发送json数据,我被卡住了。 我没有找到任何关于如何使用 apache 打开到 Web 服务器的输出流的示例。

任何帮助表示赞赏。

【问题讨论】:

  • 那么,嗯,是的...不向上/向下发送 6000 行 数据怎么样?也许分批拆分数据?
  • 再投一票不发送 6000 行数据。 dmon 应该将此作为答案而不是评论发布
  • 我试过分1000个批次,但是7分钟传输数据实在是太长了。这就是为什么我考虑使用流数据来限制数据操作和内存使用的原因。

标签: android json http post streaming


【解决方案1】:

尽管 dmon 给出了将数据拆分成批次的答案,但您应该处理其他故障。试试这个代码:

public String DonneesToJson (SQLiteDatabase db, int chantier, int chantier_serveur ) {
    Cursor c = db.rawQuery("select * from "+P_TABLE+" where "+P_CHANTIER+"="+chantier+ " order by "+P_TIME+" desc ", null);

    List<Donnees> donnees = new ArrayList<Donnees>();
    if (c != null) { // nullcheck as rawQuery can return null!
        Donnees d; // reuse variables for loops
        while (c.moveToNext()) { // was buggy before, read comment below code
            d = new Donnees (
                c.getInt(c.getColumnIndex(Datahelper.P_ID)),
                chantier_serveur,
                offset,
                c.getInt(c.getColumnIndex(Datahelper.P_PLAN)),
                c.getString(c.getColumnIndex(Datahelper.P_TIME)),
                c.getInt(c.getColumnIndex(Datahelper.P_PRESSION)),
                c.getInt(c.getColumnIndex(Datahelper.P_PROFONDEUR)),
                c.getInt(c.getColumnIndex(Datahelper.P_PROFONDEUR_TOTALE)),
                c.getInt(c.getColumnIndex(Datahelper.P_ANGLE_X)),
                c.getInt(c.getColumnIndex(Datahelper.P_ANGLE_Y)),
                c.getString(c.getColumnIndex(Datahelper.P_PIEU)),
                c.getInt(c.getColumnIndex(Datahelper.P_NO_RALLONGE)),
                c.getString(c.getColumnIndex(Datahelper.P_RALLONGE)),
                c.getInt(c.getColumnIndex(Datahelper.P_MOTEUR)),
                c.getString(c.getColumnIndex(Datahelper.P_SERIE)),
                c.getDouble(c.getColumnIndex(Datahelper.P_COEFF_A)),
                c.getDouble(c.getColumnIndex(Datahelper.P_COEFF_B)));
            donnees.add(d);
        }
        c.close();
    }
    return new Gson().toJson(donnees);
}

你当前的实现是错误的,你永远不会得到第一个条目。原因是您致电moveToFirst() 将您带到第一个。 while 循环会将内部指针移动到带有moveToNext() 的第二个条目,这将导致从第二个元素开始并完全忽略第一个元素。永远永远……

【讨论】:

  • 非常感谢您指出这一点。我知道有一个错误,因为我错过了一些行但没有看到错误。我会尝试并检查内存。
  • 只是为了说清楚:此代码不执行批量发布。我强烈建议这样做。另一个提示:如果可能,找出您是否可以计算您尝试发送的一些值。因此,如果您发送a 和b 以及加法a+b,则删除加法并在服务器端计算以减少带宽。例如:分别发送chantier_serveur和offset,因为这似乎对每个条目都是一样的......
  • 是的,我删除了 chantier_serverur 和偏移量,不再需要它们,实际上只是为了测试。所有其他值都是必需的,在发送之前我无法对它们进行任何计算。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-14
  • 2017-07-08
相关资源
最近更新 更多