3

I'm uploading multiple images one by one to server. I'm getting OOM error in the line bm = BitmapFactory.decodeFile(imagepath);. I recycled bitmap after uploading each image file but still the error is showing. Is there something wrong in my code? Also, is there any better way of uploading multiple images one by one from ArrayList?

 private void loadNext() {
        System.out.println("sammy_reached_loadNext");
        if(finalImages.size()>0){
            System.out.println("sammys_imagelist_after: "+finalImages.size());
            String path = finalImages.get(0);
            System.out.println("sammys_current_pic_path "+path);
            new UploadSingleImage(path).execute();
        }else{
            File dir = new File(file_path);
            if (dir.isDirectory()){
                String[] children = dir.list();
                if(children!=null){
                    for (int i = 0; i < children.length; i++){
                        new File(dir, children[i]).delete();
                    }
                }
            }

            pd.dismiss();
            Toast.makeText(getActivity(), "Upload Successful", Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(getActivity(), AfterPostActivity.class);
            intent.putExtra("prdid",post_id);
            startActivity(intent);
            getActivity().finish();
        }


    }

private class UploadSingleImage extends AsyncTask<Void, Void, String> {

        private HttpClient httpClient;
        private HttpPost postRequest;
        private MultipartEntity reqEntity;
        StringBuilder s;
        String imagepath;
        Bitmap bm=null;

        UploadSingleImage(String imagepath) {
            this.imagepath = imagepath;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            pd.setMessage("Please wait..");
            pd.show();
        }

        @Override
        protected String doInBackground(Void... urls) {
            try {
                httpClient = new DefaultHttpClient();

                postRequest = new HttpPost(Utility.POSTPRODIMAGES);

                reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

                reqEntity.addPart("id", new StringBody(post_id));
                Log.e("sammy_inParam_post_id", "******" + post_id);

                bm = BitmapFactory.decodeFile(imagepath);

                if (bm != null) {
                    ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
                    bm.compress(Bitmap.CompressFormat.JPEG, 100, bos1);
                    byte[] data1 = bos1.toByteArray();
                    String imgName = "myprod.jpg";
                    ByteArrayBody bab = new ByteArrayBody(data1, imgName);
                    reqEntity.addPart("image" , bab);
                }

                postRequest.setEntity(reqEntity);
                HttpResponse response = httpClient.execute(postRequest);
                BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
                String sResponse;
                s = new StringBuilder();

                while ((sResponse = reader.readLine()) != null) {
                    s = s.append(sResponse);
                }
                //System.out.println("sammy_Multiupload_doinback_Response: " + s);

            } catch (Exception e) {
                System.out.println("sammy_multiimage_doinback_excep "+e);
            }

            return s.toString();
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            System.out.println("sammys_Multiupload_onpostexec_Response: " + result);
            try {
                JSONObject jObj = new JSONObject(result);
                if (jObj.getString("ACK").equals("1")) {
                    bm.recycle();
                    finalImages.remove(0);
                    loadNext();
                }

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


        }
    }
Viral Patel
  • 32,418
  • 18
  • 82
  • 110
Somnath Pal
  • 1,570
  • 4
  • 23
  • 42

3 Answers3

1

It is crashing because you creating a lot of AsyncTask at a time. If the total number of threads running at a time reaches 138, the app will crash. So you should use executor as below

new UploadSingleImage(path).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)

The above will execute 5 tasks at a time then start the next one when previous one completes

Below are references for multiple asynctasks

http://blogs.innovationm.com/multiple-asynctask-in-android/ https://stackoverflow.com/a/4072832/2809326

Or you can use some other http libraries ion volley retrofit

Community
  • 1
  • 1
arjun
  • 3,514
  • 4
  • 27
  • 48
  • Can you show me code for uploading images using MultipartEntity in Volley. @arjun_sna – Somnath Pal Feb 09 '17 at 09:05
  • check this https://gist.github.com/anggadarkprince/a7c536da091f4b26bb4abf2f92926594 – arjun Feb 09 '17 at 09:08
  • I used your suggestion of `AsyncTask.THREAD_POOL_EXECUTOR` and also added these lines: `BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 4; bm = BitmapFactory.decodeFile(imagepath,options);` Now its working. – Somnath Pal Feb 09 '17 at 09:26
0

I don't know what's wrong but i had the same problem , it was over when i started using network libraries instead of asynktask .

I used https://github.com/koush/ion and there is also Volley .

With this you won't need to decode you can just upload a File and you won't need to be worries about the defects of the asynktask.

Asynctask is not meant for long operations and for multiple asynctasks at the same time , try my approach you will be greatfull

yanivtwin
  • 617
  • 8
  • 32
0

I'm uploading multiple images. But i see that you are uploading files. And that you first create a bitmap for each of them. Which takes a lot of memory. Then you are compressing to a byte array which takes even more memory.

Completely wrong approach.

You should just upload the bytes of the file. Do away with BitmapFactory and an intermediate Bitmap.

Just read in a loop chunks from a FileInputStream and write those chunks to the OutputStream of the connection.

In your case you could probably add a new FileBody().

greenapps
  • 11,154
  • 2
  • 16
  • 19