При синхронизации SQL Server и Android SQLite: я получил OutOfMemoryError - PullRequest
0 голосов
/ 11 августа 2011

Я делаю синхронизацию между сервером sql и sqlite. При этом я получил OutOfMemoryError. Пожалуйста, скажите мне, как мы можем избежать или из моего кода есть какие-либо нежелательные или дополнительные операторы памяти? Пожалуйста, ведите меня.

Где я могу использовать System.gc()?

Из результата сервиса получается строка в формате JSON.

{"Table1" : 
[{"ActiveStatus" : "1","AddressLine1" : "223, Dambulla Road,","AddressLine2" : "Galewela.","AddressLine3" : "","AlphaSearchCode" : "New Lanka Hardware -","BusinessUnit" : "MASS","ContactName" : "","CreatedBy" : "Nazar ","CreatedOn" : "Oct 3 2005 6:16PM","CreditLimit" : "100.00","CurrencyCode" : " ","CurrencyProcessingRequired" : "0","CurrentBalance" : "0.00","EMailAddress" : "","FaxNumber" : "","LastInvoiceDate" : "","LastPaymentDate" : "","LastPaymentValue" : "0.00","NewRetailerFlag" : "","OSOrdersPendingBase" : "0.00","OSOrdersPendingCurr" : "0.00","OnStopFlag" : "0","OnStopReasonCode" : " ","PaymentMethodCode" : "CQ","PriceGroup" : "MKT ","PricingMethod" : "0","RetailerCategoryCode" : "01 ","RetailerClassCode" : "C ","RetailerCode" : "0001 ","RetailerCodeSon" : " ","RetailerName" : "New Lanka Hardware - Galewela","RetailerTypeCode" : "02 ","RetailerTypeFlag" : "0","SalesExecutiveCode" : "THPOS ","SalesType" : "","SettlementTermsCode" : "C90","ShortAddress" : "Galewela11","StatusFlag" : "0","TelephoneNumber" : "","TempCreditApprovedInvNo" : "","TemporaryCreditAllowed" : "","TemporaryCreditApprovedBy" : "","TemporaryCreditApprovedOn" : "","TemporaryCreditLimit" : "0.00","TemporaryCreditUpto" : "","TerritoryCode" : "0001","TotalCreditsNotAllocated" : "0.00","TownCode" : "GW ","TradeSchemeGroup" : "DS ","VATCode" : "V0","VATRegistrationNo" : ""}]} 

Это одна запись. В реальном времени будет 1000 или более записей. Получив этот результат JSON, он хочет сделать оператор обновления или оператор вставки.

Мне так понравилось кодирование:

  public void loadDownloadData() {
    SoapPrimitive responsePrimitiveData;
    //Loop Table list
    for (int i = 0; i < SelectedTablesName.size(); i++) {
    try {
    responsePrimitiveData = soapPrimitiveData(SelectedTablesName.get(i));
             if (responsePrimitiveData != null) {

                try {
                    String result = responsePrimitiveData.toString();
                    if(!result.equals("0")){
                        JSONObject jsonobject = new JSONObject(result);
                        JSONArray array = jsonobject.getJSONArray("Table1");
                        int max = array.length();

                        String actualtable = getAndroidTablename(SelectedTablesName.get(i));
                        String updateType = getTableUpdateType(SelectedTablesName.get(i));
                        boolean isRecordAvailable = isTableRecords(SelectedTablesName.get(i));
                        String[] strWhereField = getTablePrimaryKey(SelectedTablesName.get(i),strBusinessUnit);

                        if (updateType.equals("1")) {
                            // Loop each table data
                            for (int j = 0; j < max; j++) {
                                JSONObject obj = array.getJSONObject(j);
                                JSONArray names = obj.names();
                                StringBuffer strFields = new StringBuffer();
                                //StringBuffer strValues = new StringBuffer();
                                String[] strToFields = new String[names.length()];
                                String[] strToFieldsVal = new String[names.length()];
                                // getting the Json name, values in separate string array
                                for (int k = 0; k < names.length(); k++) {
                                    strToFields[k] = names.getString(k);
                                    if (obj.getString(names.getString(k)) == null) {
                                        strToFieldsVal[k] = "";
                                    } else {
                                        if (obj.getString(names.getString(k)).equals(" ")) {
                                            strToFieldsVal[k] = "";
                                        } else {
                                            strToFieldsVal[k] = obj.getString(names.getString(k)).replaceAll("\\s+", "");
                                        }
                                    }
                                    strFields.append(names.getString(k) + ",");
                                } // end of json for loop
                                strFields.deleteCharAt(strFields.length() - 1);
                                if (isRecordAvailable) {
                                    String[] strWhereFieldVal = new String[strWhereField.length];
                                    StringBuffer whereFields = new StringBuffer();
                                    // making update calues where part
                                    for (int a = 0; a < strWhereField.length; a++) {
                                        strWhereFieldVal[a] = obj.getString(strWhereField[a]);
                                        String whereValues = obj.getString(strWhereField[a]).replaceAll("\\s+", "");
                                        whereFields.append(strWhereField[a]+ "= '" + whereValues+ "' and ");
                                    }
                                    // removing "and" from the end
                                    whereFields.delete(whereFields.length() - 4,whereFields.length());
                                    updateTableRecords(actualtable,strToFields, strToFieldsVal, whereFields.toString(),strWhereFieldVal);
                                } else {
                                    insertTableRecords(actualtable,strToFields, strToFieldsVal);

                                }
                            }
                        } 

                } catch (JSONException e) {
                    e.printStackTrace();
                }
                }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }
        //Log.i("***" ,SelectedTablesName.get(i));
        System.out.println(" -- " + SelectedTablesName.get(i));
        try {
            updateSuccessfulTableSoap(SelectedTablesName.get(i));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }
    }
}

Как мы можем сделать сборку мусора здесь. Я хочу сделать это string, string [], stringBuilder ссылкой на null или что я могу сделать для этого.

Ошибка:

     08-11 17:26:53.040: ERROR/AndroidRuntime(348): FATAL EXCEPTION: AsyncTask #2
08-11 17:26:53.040: ERROR/AndroidRuntime(348): java.lang.RuntimeException: An error occured while executing doInBackground()
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at java.util.concurrent.FutureTask.run(FutureTask.java:138)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at java.lang.Thread.run(Thread.java:1019)
08-11 17:26:53.040: ERROR/AndroidRuntime(348): Caused by: java.lang.OutOfMemoryError
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at java.nio.CharBuffer.put(CharBuffer.java:532)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at java.nio.charset.CharsetDecoder.allocateMore(CharsetDecoder.java:263)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:218)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at java.nio.charset.Charset.decode(Charset.java:488)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at java.lang.String.<init>(String.java:181)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at java.lang.String.<init>(String.java:141)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:96)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at com.xont.controller.DownlaodTableActivity.soapPrimitiveData(DownlaodTableActivity.java:640)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at com.xont.controller.DownlaodTableActivity.loadDownloadData(DownlaodTableActivity.java:247)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at com.xont.controller.DownlaodTableActivity$BackgroundAsyncTask.doInBackground(DownlaodTableActivity.java:795)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at com.xont.controller.DownlaodTableActivity$BackgroundAsyncTask.doInBackground(DownlaodTableActivity.java:1)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
08-11 17:26:53.040: ERROR/AndroidRuntime(348):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)

1020 * Отредактированный *

Это обработка JSON

 public void getSoapResponseTableDataJson(SoapPrimitive node,
        ArrayList<String> strings ,String loadedtable) throws JSONException {
        String result = node.toString();
        JSONObject jsonobject = new JSONObject(result);
        JSONArray array = jsonobject.getJSONArray("Table1");
        int max = array.length();

         HashMap<String, String> applicationSettings = new HashMap<String,String>();
            for(int i = 0; i < max; i++){
                String value = array.getJSONObject(i).getString("value");
                String name = array.getJSONObject(i).getString("name");
                applicationSettings.put(name, value);
            }



    }

Пожалуйста, помогите мне, как получить решение для этого ....

Заранее спасибо.

1 Ответ

2 голосов
/ 11 августа 2011

Вы используете много памяти для формирования объектов JSON из ответа сервера. Это связано с тем, что стандартные библиотеки JSON, поставляемые с Android, используют ответ whole для формирования дерева объектов JSON.

Когда вы работаете с большими объемами данных (чтобы избежать OutOfMemoryError), вам нужно формировать объекты JSON один за другим, когда вы читаете их из входного потока. Взгляните на Джексона , это позволяет вам анализировать JSON из потока, значительно сокращая потребление памяти.

Когда вы получаете ответ от сервера, используйте HttpResponse.getEntity, чтобы получить HttpEntity, на который вы можете позвонить HttpEntity.getContent, чтобы получить InputStream.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...