如何在创建JSON解析器时修复“OutOfMemoryError:java堆空间”

时间:2016-06-17 13:44:20

标签: android

我想使用http protocol.i通过JSON对象发送一些信息。我收到此错误。

UNEXPECTED TOP-LEVEL ERROR:
java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2271)
    at java.io.ByteArrayOutputStream.toByteArray(ByteArrayOutputStream.java:178)
    at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:279)
    at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166)
    at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)
    at com.android.dx.command.dexer.Main.processOne(Main.java:672)
    at com.android.dx.command.dexer.Main.processAllFiles(Main.java:569)
    at com.android.dx.command.dexer.Main.runMultiDex(Main.java:366)
    at com.android.dx.command.dexer.Main.run(Main.java:275)
    at com.android.dx.command.dexer.Main.main(Main.java:245)
    at com.android.dx.command.Main.main(Main.java:106)

 FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:dexDebug'.
> com.android.ide.common.internal.LoggedErrorException: Failed to run command:
    C:\Users\Koli\AppData\Local\Android\sdk\build-tools\23.0.0\dx.bat --dex --no-optimize --multi-dex --main-dex-list D:\Android\MedApp\app\build\intermediates\multi-dex\debug\maindexlist.txt --output D:\Android\MedApp\app\build\intermediates\dex\debug --input-list=D:\Android\MedApp\app\build\intermediates\tmp\dex\debug\inputList.txt
Error Code:
    3
Output:

    UNEXPECTED TOP-LEVEL ERROR:
    java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOf(Arrays.java:2271)
        at java.io.ByteArrayOutputStream.toByteArray(ByteArrayOutputStream.java:178)
        at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:279)
        at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166)
        at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)
        at com.android.dx.command.dexer.Main.processOne(Main.java:672)
        at com.android.dx.command.dexer.Main.processAllFiles(Main.java:569)
        at com.android.dx.command.dexer.Main.runMultiDex(Main.java:366)
        at com.android.dx.command.dexer.Main.run(Main.java:275)
        at com.android.dx.command.dexer.Main.main(Main.java:245)
        at com.android.dx.command.Main.main(Main.java:106)


* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

这是我的gradle.app

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.0"
    defaultConfig {
        applicationId "com.knitechs.www.medapp"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    productFlavors {
    }

    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/license.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/notice.txt'
        exclude 'META-INF/ASL2.0'
    }

    defaultConfig {
        multiDexEnabled = true
    }
}

dependencies {

    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.1.0'
    compile 'com.google.android.gms:play-services:+'
}

这是我的活动

package com.knitechs.www.medapp;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Spinner;

import com.knitechs.www.medapp.Transactors.PatientDetailsSender;
import com.knitechs.www.medapp.actors.Patient;

import java.util.Calendar;


public class PatientDetails extends ActionBarActivity {

    Button cmdSave;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_patient_details);

        cmdSave = (Button)findViewById(R.id.cmdSave);
        cmdSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Patient pt = new Patient();
                pt.setRecordCode(((EditText) findViewById(R.id.txtPatientRecordCode)).getText().toString());
                pt.setName(((EditText) findViewById(R.id.txtFullName)).getText().toString());
                pt.setAddress(((EditText) findViewById(R.id.txtAddress)).getText().toString());
                pt.setTelephone(((EditText) findViewById(R.id.txtTelepphoneNumber)).getText().toString());
                pt.setGardianName(((EditText) findViewById(R.id.txtGardianName)).getText().toString());
                pt.setGardianTelephone(((EditText) findViewById(R.id.txtGardianContactNumber)).getText().toString());

                final Spinner sp = (Spinner)findViewById(R.id.spnGender);
                pt.setGender(sp.getSelectedItem().toString());

                final DatePicker dob = (DatePicker) findViewById(R.id.dateDob);
                Calendar cal = Calendar.getInstance();
                cal.set(dob.getYear(),dob.getMonth(),dob.getDayOfMonth());
                pt.setBirthdate(cal.getTime());


                PatientDetailsSender patientDetailsSender = new PatientDetailsSender(pt,"php/service_classes/PatientDetails.php",getApplicationContext(),"Processing","Details Saved");
                patientDetailsSender.execute();
            }
        });
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_patient_details, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

这是我的PatientDetailsS​​ender课程

package com.knitechs.www.medapp.Transactors;

import android.content.Context;

import com.knitechs.www.medapp.actors.Patient;
import com.knitechs.www.medapp.core.JSONSender;
import com.knitechs.www.medapp.core.PDialog;

import java.util.HashMap;

/**
 * Created by Koli on
 */
public class PatientDetailsSender extends JSONSender {

    Patient patient;
    String url;
    HashMap<String,String> params;
    String message;

    public PatientDetailsSender(Patient patient,String url,Context context,String message,String successmessge){
        this.patient=patient;
        super.setSender_url(url);                   // set the send URL
        super.setCurrentActivityContext(context);   // set current context
        this.message = message;                     // set message for in process
        super.setpDialog(new PDialog(super.getCurrentActivityContext(),message));   //  ser process dialog
        super.setSuccess_message(successmessge);    // set success messge
        setPatientDataToHashMap();      // set the hash map
    }

    public void execute(){
        executeQueryCreator();
    }

    private void setPatientDataToHashMap(){

        params = new HashMap<>();

        params.put("REC_CODE",patient.getRecordCode());
        params.put("NAME",patient.getName());
        params.put("ADDRESS",patient.getAddress());
        params.put("GENDER",patient.getGender());
        params.put("GUARDIAN_NAME",patient.getGardianName());
        params.put("GUARDIAN_TP",patient.getGardianTelephone());
        params.put("B_DATE",patient.getBirthdateString());
        params.put("AGE",patient.getAgeString());
        params.put("TELEPHONE",patient.getTelephone());

    }
}

这是我的JOSNSender课程

public class JSONSender {

    private static String sender_url ;              // sender URL
    private ProgressDialog pDialog;                 // process dialog for when executing
    private Context currentActivityContext;               // current activity
    private String success_message;                 // success message when the dat inserted
    private HashMap<String,String> parameters;      // map for data for json object
    JSONParser jsonParser = new JSONParser();       // json parser
    private static final String TAG_SUCCESS = "success";

    public static void setSender_url(String sender_url) {
        JSONSender.sender_url = sender_url;
    }

    public void setpDialog(ProgressDialog pDialog) {
        this.pDialog = pDialog;
    }

    public void setParameters(HashMap<String, String> parameters) {
        this.parameters = parameters;
    }

    public void setSuccess_message(String success_message) {
        this.success_message = success_message;
    }

    public void setCurrentActivityContext(Context currentActivityContext) {
        this.currentActivityContext = currentActivityContext;
    }

    public Context getCurrentActivityContext() {
        return currentActivityContext;
    }

    protected void executeQueryCreator(){
        new QueryCreator().execute();
    }

    class QueryCreator extends AsyncTask<String, String, String> {

        /**
         * Before starting background thread Show Progress Dialog if it is having
         * */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            if(!pDialog.equals(null)){
                pDialog.show();
            }
        }

        /**
         * Do work in the save to datbse
         * */
        protected String doInBackground(String... args) {

            JSONObject json = jsonParser.makeHttpRequest(sender_url, "POST", parameters);   //  create the JSON object in parameters and send data
            Log.d("Create Response", json.toString());

            /**
             * check for success tag incomming
             */
            try {
                int success = json.getInt(TAG_SUCCESS);
                if (success == 1) {
                    Log.d("Data Saved"," OK");        // data saved indatabase
                    if(!success_message.isEmpty()){
                        Toast.makeText(getCurrentActivityContext(), success_message, Toast.LENGTH_SHORT).show();
                    }
                } else {
                    Log.d("Data Failed", " NO");       // Data failed
                    Toast.makeText(getCurrentActivityContext(),"Error",Toast.LENGTH_SHORT).show();
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }

            return null;
        }

        /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(String file_url) {
            // dismiss the dialog once done
            if(!pDialog.equals(null)){
                pDialog.dismiss();
            }
        }

    }
}

这是我的JSONParser类

package com.knitechs.www.medapp.core;

import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;

/**
 * Created by Koli on
 */
public class JSONParser {

    String charset = "UTF-8";       // character type
    HttpURLConnection conn;         // HTTP connection
    DataOutputStream wr;            // Data output stream for get out data from database
    StringBuilder result;           // reciving data string
    URL urlObj;                     // URL object for the connection
    JSONObject jObj = null;         // Json object for create Json parsers
    StringBuilder sbParams;         // string for create parameter url
    String paramsString;            // sending parameter url string
    private String ipaddress ="http://192.168.8.100/";  //IP address of theserver

    /**
     * @param url_path    url for the servenr php service class  without the ip (folder/pages)
     * @param method port or get method
     * @param params json object parmeters
     * @return JSON object returns with include HTTP URL
     */

    public JSONObject makeHttpRequest(String url_path, String method, HashMap<String, String> params) {

        sbParams = new StringBuilder();             // create new string for theparameters
        int i = 0;
        /**
         * create the URL parameter string from key set and values
         * key=value & key=value like that
         */
        for (String key : params.keySet()) {
            try {
                if (i != 0) {
                    sbParams.append("&");
                }
                sbParams.append(key).append("=")
                        .append(URLEncoder.encode(params.get(key), charset));

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            i++;
        }

        /**
         * create the connection URL
         */

        String url = ipaddress + url_path ;

        /**
         * create the connection object byVal method
         */

        if (method.equals("POST")) {

            /**
             * request port method
             */

            try {
                urlObj = new URL(url);                                  //  create a URL object
                conn = (HttpURLConnection) urlObj.openConnection();     //  create a HTTP connection object from theURL object
                conn.setDoOutput(true);                                 //  set the method type as Output
                conn.setRequestMethod("POST");                          //  Request method as POST
                conn.setRequestProperty("Accept-Charset", charset);     //  chrctor acceptance
                conn.setReadTimeout(10000);                             //  readable timeout for reading
                conn.setConnectTimeout(15000);                          //  connection time out for connect to server
                conn.connect();

                paramsString = sbParams.toString();                     //  parameter string

                wr = new DataOutputStream(conn.getOutputStream());      //  write the output stream to the Dtoutput stream
                wr.writeBytes(paramsString);
                wr.flush();
                wr.close();

            } catch (IOException e) {
                e.printStackTrace();
            }

        } else if (method.equals("GET")) {

            /**
             * request get method
             */

            if (sbParams.length() != 0) {
                url += "?" + sbParams.toString();   //  url ? key = val1 & key = val2
            }

            try {
                urlObj = new URL(url);                              //  create a URL object
                conn = (HttpURLConnection) urlObj.openConnection(); //  create a HTTP connection object from theURL object
                conn.setDoOutput(false);                            //  set the method type as Output
                conn.setRequestMethod("GET");                       //  Request method as GET
                conn.setRequestProperty("Accept-Charset", charset); //  chrctor acceptance
                conn.setConnectTimeout(15000);                      //  connection time out for connect to server
                conn.connect();

            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        /**
         *  response comes from server for request message this is also as a data input stream,same connection c
         */

        try {
            InputStream in = new BufferedInputStream(conn.getInputStream());        //  input strem
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));  //  Buffer reader for the reader od connection statements,inpu string
            result = new StringBuilder();                                           //  respond message
            String line;
            /**
             * append the lines in to single result string
             */
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }

            Log.d("JSON Parser", "result: " + result.toString());

        } catch (IOException e) {
            e.printStackTrace();
        }

        conn.disconnect();          // disconnect the connection

        /**
         * parse the string to a json object
         */

        try {
            jObj = new JSONObject(result.toString());
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }
        return jObj;    // return json object
    }
}

这是我的PDialog类

package com.knitechs.www.medapp.core;

import android.app.ProgressDialog;
import android.content.Context;

/**
 * Created by Koli on
 */
public class PDialog extends ProgressDialog {

    public PDialog(Context context) {
        super(context);
    }

    public PDialog(Context context,String message){
        super(context);
        super.setMessage(message);
        super.setIndeterminate(false);
    }
}

我很困惑为什么我得到这个错误。请帮助我。

1 个答案:

答案 0 :(得分:1)

在android项目build.gradle文件中增加javamaxheapsize可能可以解决问题。

android {
  ...
  dexOptions {
      javaMaxHeapSize "4g"
  }
}

请参阅此处了解更多信息。

Implementing MultiDex results in compiling for so long, and finally heap space error

Android Studio - How to increase Allocated Heap Size