title: java.lang.OutOfMemoryError: Could not allocate JNI Env
body: <p>When I first time run Async task its works fine. Actually this error comes unpredictably. I search lots of solutions on this issue but nothing is works for me.
  Common Solution which i got is, we need to close InputStream/ByteArrayInputStream &amp; I closed all but still app gets crash.</p>
  
  <p>Stacktrace:</p>
  
  <blockquote>
    <p>java.lang.OutOfMemoryError: Could not allocate JNI Env at
    java.lang.Thread.nativeCreate(Native Method) at
    java.lang.Thread.start(Thread.java:730) at
    java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:941)
    at
    java.util.concurrent.ThreadPoolExecutor.processWorkerExit(ThreadPoolExecutor.java:1009)
    at
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1151)
    at
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:761)</p>
  </blockquote>
  
  <p>Following is AsyncTask;</p>
  
  <pre><code>public class AsyncHttpRequest extends AsyncTask&lt;Void, Void, String&gt; {
  
      private String UrlString = "";
      private boolean _showProgressDialog = false;
      private CustomCircularLoadingDialog Dialog;
      private Context mContext;
      AppCompatActivity mActivity;
      private IHttpRequestCompletedListener listener;
      private boolean isActivity = true;
      private String _messageText = "Please wait..."; 
      private String type = "get";
  
      private HttpUtility utility;
  
  
      public AsyncHttpRequest(String urlString, Context context, IHttpRequestCompletedListener listener, boolean _showProgressDialog) {
          UrlString = urlString;
          this._showProgressDialog = _showProgressDialog;
          this.mContext = context;
          this.listener = listener;
          Dialog = new CustomCircularLoadingDialog(this.mContext);
          this.utility = new HttpUtility(this.UrlString, mContext);
          Utilities.setCurrentHitURL(mContext, UrlString);
      }
  
      public void setOnCompletedListener(IHttpRequestCompletedListener listener) {
          this.listener = listener;
      }
  
      public void setWaitMessage(String msgText) {
          if (!msgText.equals(""))
              msgText = "\n" + msgText;
          this._messageText = _messageText + msgText;
      }
  
      public void addPostItem(NameValuePair nameValuePair) {
          this.utility.addNameValuePairs(nameValuePair);
      }
  
      public void addGetHeader(String headerData) {
          this.utility.addGetHeader(headerData);
      }
  
      public void addPostHeader(String headerData) {
          this.utility.addPostHeader(headerData);
      }
  
      public void setTypePost() {
          this.type = "post";
      }
  
      @Override
      protected void onPreExecute() {
          if (_showProgressDialog) {
              Dialog.setMessage(this._messageText);
              Dialog.setCancelable(false);
              Dialog.setCanceledOnTouchOutside(false);
              this.Dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
              Dialog.show();
          }
      }
  
      @Override
      protected String doInBackground(Void... params) {
  
          if (!Utilities.isNetworkAvailable(mContext))
              return "No network available";
          try {
              if (this.type.equals("get"))
                  return utility.doGetRequest();
              else
                  return utility.doPostRequest();
          } catch (MediCorporateException tex) {
  
              if (listener != null) {
                  if (isActivity) {
                      ((Activity) mContext).runOnUiThread(new Runnable() {
                          @Override
                          public void run() {
                              listener.OnHttpRequestError();
                          }
                      });
                  } else {
                      ((GcmIntentService) mContext).runOnUIThread(new Runnable() {
                          @Override
                          public void run() {
                              listener.OnHttpRequestError();
                          }
                      });
                  }
              }
              Utilities.callCrashReport(mContext, tex);
          }
          Log.i("Exit ", "doInBackground");
  
          return "";
      }
  
      @Override
      protected void onPostExecute(String Result) {
          if (_showProgressDialog)
              this.Dialog.dismiss();
          Log.i("Came in", "onPostExecute");
          if (this.listener != null) {
              if (!Utilities.isNullOrEmpty(Result))
                  listener.OnHttpRequestCompleted(Result);
              else {
                  logoutUser();
                  listener.OnHttpRequestError();
              }
          }
          Log.i("Exit ", "onPostExecute");
      }
  
  }
  </code></pre>
  
  <p>Following are functions to handle request &amp; responses in HttpUtility class;</p>
  
  <pre><code>public String doGetRequest() throws MediCorporateException {
  
          String resp = "";
          int responseCode = 0;
          try {
              if (header != null) {
                  if (header.length() &gt; 0) {
                      httpURLConnection.setRequestMethod("GET");
                      httpURLConnection.setRequestProperty("Authorization", header);
                  }
              }
              responseCode = httpURLConnection.getResponseCode();
              InputStream inputStream = new BufferedInputStream(this.httpURLConnection.getInputStream());
              resp = readResponse(inputStream);
              Log.v("Resp", "" + responseCode + " --- " + resp);
              inputStream.close();
          } catch (IOException ioExc) {
              FileLog.e(getClass().getName(), ioExc);
              resp = ioExc.getMessage();
              throw new MediCorporateException("Http IO Exception...");
          } catch (Exception ex) {
              FileLog.e(getClass().getName(), ex);
              throw new MediCorporateException("Http Error...");
          } finally {
  
              this.httpURLConnection.disconnect();
              if (responseCode == 401)
                  return "" + responseCode;
              if (responseCode != 200)
                  return null;
          }
  
          return resp;
      }
  </code></pre>
  
  <p>Following is DoPostRequest() :</p>
  
  <pre><code>public String doGetRequest() throws MediCorporateException {
  
          String resp = "";
          int responseCode = 0;
          try {
              if (header != null) {
                  if (header.length() &gt; 0) {
                      httpURLConnection.setRequestMethod("GET");
                      httpURLConnection.setRequestProperty("Authorization", header);
                  }
              }
              responseCode = httpURLConnection.getResponseCode();
              InputStream inputStream = new BufferedInputStream(this.httpURLConnection.getInputStream());
              resp = readResponse(inputStream);
              Log.v("Resp", "" + responseCode + " --- " + resp);
              inputStream.close();
          } catch (IOException ioExc) {
              FileLog.e(getClass().getName(), ioExc);
              resp = ioExc.getMessage();
              throw new MediCorporateException("Http IO Exception...");
          } catch (Exception ex) {
              FileLog.e(getClass().getName(), ex);
              throw new MediCorporateException("Http Error...");
          } finally {
  
              this.httpURLConnection.disconnect();
              if (responseCode == 401)
                  return "" + responseCode;
              if (responseCode != 200)
                  return null;
          }
  
          return resp;
      }
  </code></pre>
  
  <p>following is reading &amp; writing response functions;</p>
  
  <pre><code>private void writePostMethod(OutputStream outputStream) throws Exception {
          if (this.nameValuePairs.size() &lt;= 0)
              throw new Exception("Cannot use post method with no values to post");
          String postStr = "";
          for (NameValuePair item : this.nameValuePairs)
              postStr += URLEncoder.encode(item.getName(), "UTF-8") + "=" + URLEncoder.encode(item.getValue(), "UTF-8") + "&amp;";
          postStr = postStr.substring(0, postStr.length() - 1);
          Log.v("Post Values", postStr);
          BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
          writer.write(postStr);
          writer.flush();
          writer.close();
      }
  
      private String readResponse(InputStream inputStream) throws IOException {
          int i;
          ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
          while ((i = inputStream.read()) != -1)
              outputStream.write(i);
  
          byte[] responseBytes = outputStream.toByteArray();
          ByteArrayInputStream bais = new ByteArrayInputStream(responseBytes);
          InputStreamReader reader;
          if (!this._urlString.contains("token")) {
              GZIPInputStream gzis = new GZIPInputStream(bais);
              reader = new InputStreamReader(gzis);
              gzis.close();
          } else
              reader = new InputStreamReader(bais);
  
          BufferedReader in = new BufferedReader(reader);
          StringBuilder total = new StringBuilder();
          String readed;
          while ((readed = in.readLine()) != null) {
              total.append(readed);
              bais.close();
          }
          in.close();
          reader.close();
          inputStream.close();
          outputStream.close();
          return total.toString();
      }
  </code></pre>