上传图片时我得到了java.lang.OutOfMemoryError

时间:2015-10-08 07:39:49

标签: android performance

这是我的活动代码,我使用asynctask来上传文件,我只是传递了图像路径数组。它还显示了其他一些数组,请检查错误日志中的其他错误。

 private class ServiceSync extends AsyncTask<ArrayList<String>, Integer, List<String>> {

        private String res;
        private String boundary;
        private String LINE_FEED = "\r\n";
        private Context context;
        private HttpURLConnection httpConn;
        private String charset = "UTF-8";
        ;
        private OutputStream outputStream;
        private PrintWriter writer;
        ProgressDialog mProgressDialog;
        String requestURL = "URL";

        int count;

        @Override
        protected void onPreExecute() {
            res = null;
            count = 0;
            //mProgressDialog = ProgressDialog.show(Create_NewsFeed.this, "","Uploading image");
            mProgressDialog = new ProgressDialog(Create_NewsFeed.this);
            mProgressDialog.setMessage("Posting.. please wait...");
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            mProgressDialog.setMax(100);
//            mProgressDialog.show();
            try {
                // creates a unique boundary based on time stamp
                boundary = "===" + System.currentTimeMillis() + "===";

                URL url = new URL(requestURL);
                httpConn = (HttpURLConnection) url.openConnection();
                httpConn.setUseCaches(false);
                httpConn.setDoOutput(true); // indicates POST method
                httpConn.setDoInput(true);
                httpConn.setRequestProperty("Content-Type",
                        "multipart/form-data; boundary=" + boundary);
                httpConn.setRequestProperty("User-Agent", "CodeJava Agent");
                httpConn.setRequestProperty("Test", "Bonjour");
                outputStream = httpConn.getOutputStream();
                writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
                        true);

                writer.append("User-Agent" + ": " + "CodeJava").append(LINE_FEED);
                writer.flush();
                writer.append("Test-Header" + ": " + "Header-Value").append(LINE_FEED);
                writer.flush();

            } catch (Exception e) {
            }
        }

        @Override
        protected List<String> doInBackground(ArrayList<String>... imgPaths) {
            try {

                // Start parameter
                addFormField("user_id", imgPaths[1].get(0)); //pass user_id
                addFormField("description", imgPaths[1].get(1)); //pass description
                addFormField("post_date", "1"); //pass user_id
                addFormField("post_type", imgPaths[1].get(2)); //pass user_id
                addFormField("price", "1000"); //pass user_id
                //End parameter

                File sourceFile[] = new File[imgPaths[0].size()];
                for (int i = 0; i < imgPaths[0].size(); i++) {
                    sourceFile[i] = new File(imgPaths[0].get(i));
                }

                for (int i = 0; i < imgPaths[0].size(); i++) {
                    addFilePart("uploaded_file[]", sourceFile[i]);
                    count++;
                }
                return multipartfinish();

            } catch (Exception e) {
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            mProgressDialog.setProgress(values[0]);
        }

        @Override
        protected void onPostExecute(List<String> ress) {
            try {
                if (ress == null) {
                    mProgressDialog.dismiss();
                    Toast.makeText(getApplicationContext(), "Failed to upload files", Toast.LENGTH_SHORT).show();
                }

                if (ress.size() > 0) {
                    for (int i = 0; i < ress.size(); i++) {
                        Toast.makeText(getApplicationContext(), ress.get(i), Toast.LENGTH_SHORT).show();
                    }
                }

                mProgressDialog.dismiss();
                Intent i = new Intent(Create_NewsFeed.this,NewsFeed.class);
                startActivity(i);
                finish();
            } catch (Exception objEx) {
                objEx.printStackTrace();
            }
            mProgressDialog.dismiss();
        }


        public void addFilePart(String fieldName, File uploadFile)
                throws IOException {

            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
            String ext = uploadFile.getName().substring(uploadFile.getName().lastIndexOf(".") + 1);
            String fileName = simpleDateFormat.format(new Date()) + count + "." + ext;

            // String fileName = uploadFile.getName();
            writer.append("--" + boundary).append(LINE_FEED);
            writer.append(
                    "Content-Disposition: form-data; name=\"" + fieldName
                            + "\"; filename=\"" + fileName + "\"")
                    .append(LINE_FEED);
            writer.append(
                    "Content-Type: "
                            + URLConnection.guessContentTypeFromName(fileName))
                    .append(LINE_FEED);
            writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
            writer.append(LINE_FEED);
            writer.flush();

            FileInputStream inputStream = new FileInputStream(uploadFile);

            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            if (ext.equals("png")) {
                bitmap.compress(Bitmap.CompressFormat.PNG, 30, stream); //compress to which format you want.
            } else {
                bitmap.compress(Bitmap.CompressFormat.JPEG, 30, stream); //compress to which format you want.
            }

            // byte [] buffer = stream.toByteArray();

            InputStream in = new ByteArrayInputStream(stream.toByteArray());
            int totalfilesize = in.available();

            byte[] buffer = new byte[4096];

            int bytesRead = -1;
            int bytesend = 0;
            while ((bytesRead = in.read(buffer)) != -1) {
                int progress = (int) ((bytesend / (float) totalfilesize) * 100);
                bytesend += bytesRead;
                if (bytesRead <= totalfilesize) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                publishProgress(progress);
            }
            outputStream.flush();
            inputStream.close();

            writer.append(LINE_FEED);
            writer.flush();
        }

        public void addFormField(String name, String value) {
            writer.append("--" + boundary).append(LINE_FEED);
            writer.append("Content-Disposition: form-data; name=\"" + name + "\"")
                    .append(LINE_FEED);
            writer.append("Content-Type: text/plain; charset=" + charset).append(
                    LINE_FEED);
            writer.append(LINE_FEED);
            writer.append(value).append(LINE_FEED);
            writer.flush();
        }

        public List<String> multipartfinish() throws IOException {
            List<String> response = new ArrayList<String>();

            writer.append(LINE_FEED).flush();
            writer.append("--" + boundary + "--").append(LINE_FEED);
            writer.close();

            // checks server's status code first
            int status = httpConn.getResponseCode();
            if (status == HttpURLConnection.HTTP_OK) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(
                        httpConn.getInputStream()));
                String line = null;
                while ((line = reader.readLine()) != null) {
                    response.add(line);
                }
                writer.print("");
                writer.flush();
                reader.close();
                httpConn.disconnect();
            } else {
                throw new IOException("Server returned non-OK status: " + status);
            }

            return response;
        }
    }

这是我的logcat,我在Bitmap bitmap = BitmapFactory.decodeStream(inputStream)上得到了错误;这条线,不知道出了什么问题,请帮帮我。

10-08 13:02:24.745  13450-13454/fourever.textile D/dalvikvm﹕ GC_CONCURRENT freed 1582K, 13% free 52794K/60295K, paused 12ms+15ms, total 69ms
10-08 13:02:25.435  13450-14845/fourever.textile D/dalvikvm﹕ GC_FOR_ALLOC freed 492K, 13% free 52542K/60295K, paused 34ms, total 34ms
10-08 13:02:25.435  13450-14845/fourever.textile I/dalvikvm-heap﹕ Forcing collection of SoftReferences for 7680016-byte allocation
10-08 13:02:25.485  13450-14845/fourever.textile D/dalvikvm﹕ GC_BEFORE_OOM freed 10K, 13% free 52532K/60295K, paused 49ms, total 49ms
10-08 13:02:25.485  13450-14845/fourever.textile E/dalvikvm-heap﹕ Out of memory on a 7680016-byte allocation.
10-08 13:02:25.485  13450-14845/fourever.textile I/dalvikvm﹕ "AsyncTask #3" prio=5 tid=21 RUNNABLE
10-08 13:02:25.485  13450-14845/fourever.textile I/dalvikvm﹕ | group="main" sCount=0 dsCount=0 obj=0x423b7c98 self=0x5d07d078
10-08 13:02:25.485  13450-14845/fourever.textile I/dalvikvm﹕ | sysTid=14845 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=1616684464
10-08 13:02:25.485  13450-14845/fourever.textile I/dalvikvm﹕ | schedstat=( 70530999 15854792 28 ) utm=6 stm=1 core=0
10-08 13:02:25.485  13450-14845/fourever.textile I/dalvikvm﹕ at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
10-08 13:02:25.490  13450-14845/fourever.textile I/dalvikvm﹕ at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:663)
10-08 13:02:25.490  13450-14845/fourever.textile I/dalvikvm﹕ at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:735)
10-08 13:02:25.490  13450-14845/fourever.textile I/dalvikvm﹕ at fourever.textile.mainclasses.Create_NewsFeed$ServiceSync.addFilePart(Create_NewsFeed.java:545)
10-08 13:02:25.490  13450-14845/fourever.textile I/dalvikvm﹕ at fourever.textile.mainclasses.Create_NewsFeed$ServiceSync.doInBackground(Create_NewsFeed.java:481)
10-08 13:02:25.490  13450-14845/fourever.textile I/dalvikvm﹕ at fourever.textile.mainclasses.Create_NewsFeed$ServiceSync.doInBackground(Create_NewsFeed.java:411)
10-08 13:02:25.495  13450-14845/fourever.textile I/dalvikvm﹕ at android.os.AsyncTask$2.call(AsyncTask.java:287)
10-08 13:02:25.495  13450-14845/fourever.textile I/dalvikvm﹕ at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
10-08 13:02:25.495  13450-14845/fourever.textile I/dalvikvm﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:137)
10-08 13:02:25.495  13450-14845/fourever.textile I/dalvikvm﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
10-08 13:02:25.495  13450-14845/fourever.textile I/dalvikvm﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
10-08 13:02:25.495  13450-14845/fourever.textile I/dalvikvm﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
10-08 13:02:25.500  13450-14845/fourever.textile I/dalvikvm﹕ at java.lang.Thread.run(Thread.java:856)
10-08 13:02:25.500  13450-14845/fourever.textile I/dalvikvm﹕ [ 10-08 13:02:25.500 13450:14845 D/skia     ]
    --- decoder->decode returned false
10-08 13:02:25.500  13450-14845/fourever.textile W/dalvikvm﹕ threadid=21: thread exiting with uncaught exception (group=0x40de72a0)
10-08 13:02:25.515  13450-14845/fourever.textile E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #3
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:299)
            at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
            at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            at java.lang.Thread.run(Thread.java:856)
     Caused by: java.lang.OutOfMemoryError
            at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
            at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:663)
            at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:735)
            at fourever.textile.mainclasses.Create_NewsFeed$ServiceSync.addFilePart(Create_NewsFeed.java:545)
            at fourever.textile.mainclasses.Create_NewsFeed$ServiceSync.doInBackground(Create_NewsFeed.java:481)
            at fourever.textile.mainclasses.Create_NewsFeed$ServiceSync.doInBackground(Create_NewsFeed.java:411)
            at android.os.AsyncTask$2.call(AsyncTask.java:287)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
            at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            at java.lang.Thread.run(Thread.java:856)
10-08 13:02:36.530  13450-13450/fourever.textile I/Choreographer﹕ Skipped 623 frames!  The application may be doing too much work on its main thread.
10-08 13:02:36.630  13450-13450/fourever.textile D/SensorManager﹕ unregisterListener:: Trklfufi 9 budiwrd5mrfo5WirfulblrwuFmfulTrklfufi$KfukwiFmfulTrklfufiRvht@,)+be:*(
10-08 13:02:36.630  13450-13450/fourever.textile D/Sensors﹕ Remain listener = Sending .. normal delay 200ms
10-08 13:02:36.630  13450-13450/fourever.textile I/Sensors﹕ sendDelay --- 200000000
10-08 13:02:36.630  13450-13450/fourever.textile D/SensorManager﹕ JNI - sendDelay
10-08 13:02:36.630  13450-13450/fourever.textile I/SensorManager﹕ Set normal delay = true

3 个答案:

答案 0 :(得分:1)

有几种方法可以解决这个问题。首先,您可以使用其他颜色方案或其他比例加载图像。请注意,你会失去一些品质。

BitmapFactory.Options options = new BitmapFactory.Options();
//swt the color scheme to something less memory consuming
options.inPreferredConfig = Config.RGB_565;
//scale the image by factor 2
options.inSampleSize = 2;
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);

另见this page

您可以做的另一件事是为应用启用大堆大小,您可以在manifest中添加

android:largeHeap="true"

application代码。

答案 1 :(得分:0)

您正在主线程上执行网络操作。将您的网络请求代码放在doInBackGround()而不是OnPreExecute()中。 并检查图像的大小,这可能是问题的原因。

答案 2 :(得分:0)

请在文件上传类中添加以下行:

httpConn.setChunkedStreamingMode(1024);

您可以根据设备堆大小修改1024大小

有关详细信息,请参阅此链接:

http://technet.weblineindia.com/mobile/upload-large-video-on-server-using-multipart-in-android/