【发布时间】:2017-02-11 14:29:17
【问题描述】:
我正在尝试使用 json ( 13.8 MB ) 将 GPS 坐标的整个 (50K 行) mysql 数据库服务器数据及其信息发送到 Android 手机第一次运行我的应用程序,我遇到了很多重大问题!,
我用来从 php yii2 控制器发送 json 数据的代码是:
public function actionGetGPS(){
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
Yii::$app->response->data["success"] = true;
Yii::$app->response->data["gps"] = \app\models\gps::findAll();
}
在 android 部分,AsyncTask 获取 json 文件,我使用了以下代码:
public static class getGpsDataForFirstTimeRun extends AsyncTask<String, String, JSONObject> {
@Override
protected void onPreExecute() {}
@Override
protected JSONObject doInBackground(String... args) {
try {
HashMap<String, String> params = new HashMap<>();
// App.URL_GET_GPS = "http://localhost/myproject/web/gps/get-gps"
JSONObject jsonObject = JSONParser.MakeHttpRequest(App.URL_GET_Gps, "POST", params);
if (jsonObject != null) {
try {
if (jsonObject.getBoolean(App.TAG_SUCCESS)) {
App.Log("Saving Json Data");
JSONArray jsonArray = jsonObject.getJSONArray("Gps");
for (int i = 0; i < (jsonArray.length()); i++) {
JSONObject jObject = (JSONObject)jsonArray.get(i);
// App.db = new DBHelper();
App.db.addGps(jObject.getInt("id"), jObject.getInt("city_id"), jObject.getDouble("latitude"), jObject.getDouble("longitude"));
App.Log("Inserted: "+jObject.toString());
}
App.Log("Json Data Saved");
}
}
catch (JSONException e) {
e.printStackTrace();
}
return null;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(JSONObject jsonObject) {}
}
在 dbhelper 中我有这个添加 GPS 的功能:
public void addGps(int Gps_id, int city, double latitude, double longitude) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(GPS_COLUMN_ID, Gps_id);
values.put(GPS_COLUMN_CITY_ID, city);
values.put(GPS_COLUMN_LATITUDE, latitude);
values.put(GPS_COLUMN_LONGITUDE, longitude);
db.insert(GPS_TABLE_NAME, null, values);
//db.close(); // Closing database connection // Updated Question
App.Log("New Gps inserted into SQLite: " + Gps_id);
}
问题1:PHP服务器内存:134217728字节的允许内存大小已用完
解决方案 1:我使用此行代码使其不受限制:
ini_set('memory_limit', '-1');
问题 2:但是我发现这根本不实用,如果你有 +1000 用户,服务器可能会窒息..
解决方案 2:所以我发现的唯一方法是每 24 小时获取一次我的数据,并将其放入服务器上的 json 文件中,如果它在数据库中发生更改,我将运行查询来更新它。以此类推,所以用户新下载应用程序时,会得到最新的数据,老用户可以从数据库中下载新数据,因为它是小改动..
我的问题是:这种方法好吗?还是有更好的?
问题 3:android 部分 :( 50K 数据未插入到 sqlite,我收到此错误:
10-03 17:47:39.381 702-702/com.myproject.gps E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.myproject.gps, PID: 702
java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed.
at android.database.sqlite.SQLiteConnectionPool.throwIfClosedLocked(SQLiteConnectionPool.java:1027)
at android.database.sqlite.SQLiteConnectionPool.waitForConnection(SQLiteConnectionPool.java:742)
at android.database.sqlite.SQLiteConnectionPool.acquireConnection(SQLiteConnectionPool.java:397)
at android.database.sqlite.SQLiteSession.acquireConnection(SQLiteSession.java:905)
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:834)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:147)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:136)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:197)
at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:237)
at com.myproject.gps.Tools.Instance.DBHelper.getGps(DBHelper.java:337)
at com.myproject.gps.Dashboard.GPSMapFragment.onCameraIdle(GPSMapFragment.java:119)
at com.google.android.gms.maps.GoogleMap$21.onCameraIdle(Unknown Source)
at com.google.android.gms.maps.internal.zzf$zza.onTransact(Unknown Source)
at android.os.Binder.transact(Binder.java:380)
at uv.a(:com.google.android.gms.DynamiteModulesB:79)
at maps.ad.j.b(Unknown Source)
at maps.ad.j.a(Unknown Source)
at maps.ad.j$2.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5951)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
解决方案 3:我尝试将 json 文件:就好像我下载它一样,在 Asset 文件夹中,并尝试从那里插入 json 数据:它工作但!
问题 4:将 50,000 条 json 数据插入 sqlite 大约需要 15 分钟。
仍然没有找到解决方案!,任何建议或 cmets 将不胜感激..
【问题讨论】:
-
为什么每次插入后都要关闭 sqlite 数据库?这就像开车去商店买杂货,买一罐牛奶,开车回家,把它放在冰箱里,然后开车回到商店,买一条面包,开车回家等等......非常无能为力。跨度>
-
哇!我没想到这个……让我试试看:)
-
1.使用一些 json 流 API ..2。使用事务 3. 更好地同步 - fx 将最后修改时间戳放到行中,并仅下载下载时间戳大于请求中给定的行 ...
-
花了 10 分钟,将其全部插入,这是一个改进..@MarcB 先生您还有其他通知吗非常感谢..
-
SQLite 中的 sql 事务 ... google 关于它(android 有此 API).... 3 更好的同步简单概念:
table(id, city_id, latitude, longitude, timestamp)...您在行插入/更新时修改时间戳服务器端...您的findAll将时间戳作为参数并仅返回具有较大时间戳的行...服务器还返回最后一个时间戳,客户端将其存储以供下一次同步...。要做:如何处理删除(编辑:简单的解决方案不要删除 - 使用标志“已删除”)
标签: php android mysql json sqlite