将大型JSON数据从php mysql服务器加载到java android客户端

时间:2016-10-03 15:23:47

标签: php android mysql json sqlite

我正在尝试使用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:花费15分钟将50,000个json数据插入sqlite ..

仍然没有为此找到解决方案!任何建议或意见都将不胜感激..

1 个答案:

答案 0 :(得分:3)

是否可以让您的应用程序逐个下载GPS数据?首次安装可能只是最接近用户的10000行坐标。然后,您可以按计划在后台运行其余数据更新。