上传多个图像时出现OutOfMemoryError

时间:2017-02-09 08:53:38

标签: android out-of-memory

我将多个图片逐个上传到服务器。我在行bm = BitmapFactory.decodeFile(imagepath);中收到OOM错误。我在上传每个图像文件后回收了位图,但仍然显示错误。我的代码中有什么问题吗?另外,有没有更好的方法从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();
            }


        }
    }

3 个答案:

答案 0 :(得分:1)

它崩溃了,因为你一次创建了很多AsyncTask。如果一次运行的线程总数达到138,则应用程序将崩溃。因此,您应该使用executor,如下所示

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

以上将一次执行5个任务,然后在前一个任务完成时启动下一个任务

以下是多个asynctasks的参考资料

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

或者您可以使用其他一些http库ion volley retrofit

答案 1 :(得分:0)

我不知道出了什么问题,但我遇到了同样的问题,当我开始使用网络库而不是asynktask时,它已经结束了。

我使用了https://github.com/koush/ion,还有Volley。

有了这个你就不需要解码就可以上传一个文件了,你不必担心asynktask的缺陷。

Asynctask不适用于长时间操作和同时多个asynctasks,试试我的方法你会很棒

答案 2 :(得分:0)

I'm uploading multiple images。但我发现你正在上传文件。并且您首先为每个人创建一个位图。这需要大量的记忆。然后你压缩到一个占用更多内存的字节数组。

完全错误的方法。

您应该只上传文件的字节。取消BitmapFactory和中间位图。

只需从FileInputStream中读取一个循环块,然后将这些块写入连接的OutputStream。

在您的情况下,您可能会添加一个新的FileBody()。