在android中,将图像输入流读取到数组需要很长时间

在android中,将图像输入流读取到数组需要很长时间,android,android-asynctask,Android,Android Asynctask,图像很小(400Kb),但需要很长时间才能读取。下面代码中的第一个while循环花费了很多时间(在某些情况下,它的速度非常快)此行为的任何原因,如何使其一致。此代码在asyctask中执行,如下所示。它还显示一个进度对话框 更多详细信息:我正在从服务器下载png。我的目标是获得图像边界并对其进行采样,以避免内存问题。如果我只使用一个输入流来获取边界,我就无法再次使用它来获取图像。这就是为什么我必须创建两个副本。问题在于while循环以不可预测的方式持续很长时间。有时它的加载速度非常快 publi

图像很小(400Kb),但需要很长时间才能读取。下面代码中的第一个while循环花费了很多时间(在某些情况下,它的速度非常快)<代码>此行为的任何原因,如何使其一致。此代码在asyctask中执行,如下所示。它还显示一个进度对话框

更多详细信息:我正在从服务器下载png。我的目标是获得图像边界并对其进行采样,以避免内存问题。如果我只使用一个输入流来获取边界,我就无法再次使用它来获取图像。这就是为什么我必须创建两个副本。问题在于while循环以不可预测的方式持续很长时间。有时它的加载速度非常快

public static Bitmap decodeBitmapFromInputStream(InputStream inputStream,
                                                     int reqWidth, int reqHeight, boolean checkLen) {
        byte[] byteArr = new byte[0];
        byte[] buffer = new byte[1024];
        int len;
        int count = 0;

        try {

            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            while ((len = inputStream.read(buffer)) > -1 ) {
                baos.write(buffer, 0, len);
            }
            baos.flush();

            InputStream is1 = new ByteArrayInputStream(baos.toByteArray());
            InputStream is2 = new ByteArrayInputStream(baos.toByteArray());

            /*while ((len = inputStream.read(buffer)) > -1) {
                if (len != 0) {
                    if (count + len > byteArr.length) {
                        byte[] newbuf = new byte[(count + len) * 2];
                        System.arraycopy(byteArr, 0, newbuf, 0, count);
                        byteArr = newbuf;
                    }

                    System.arraycopy(buffer, 0, byteArr, count, len);
                    count += len;
                }
            }*/

            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
           // BitmapFactory.decodeByteArray(byteArr, 0, count, options);
            BitmapFactory.decodeStream(is1, null, options);

            if (checkLen) {
                if (options.outHeight == options.outWidth) {
                    reqWidth = (int) (reqWidth * 0.9);
                    reqHeight = reqWidth;
                } else {
                    reqWidth = (int) (reqWidth * 0.75);
                    reqHeight = (int) (reqWidth * 0.75);
                }
            }

            options.inSampleSize = calculateInSampleSize(options, reqWidth,
                    reqHeight);
            options.inPurgeable = true;
            options.inInputShareable = true;
            options.inJustDecodeBounds = false;

            //Bitmap b = BitmapFactory.decodeByteArray(byteArr, 0, count, options);
            Bitmap b = BitmapFactory.decodeStream(is2, null, options);

            Matrix matrix = new Matrix();
            int width = b.getWidth();
            int height = b.getHeight();

            // calculate the scale - in this case = 0.4f
            float scaleWidth = ((float) reqWidth) / width;
            float scaleHeight = ((float) reqHeight) / height;
            matrix.postScale(scaleWidth, scaleHeight);

            Bitmap scaled = b.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(),
                    matrix, true);

            b.recycle();
            b = null;
            return scaled;

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

            return null;
        }
    }


protected Bitmap doInBackground(String... param) {

            Log.w("myApp", "doInBackground");
            Bitmap bm = null;
            InputStream is = null;
            if (mode == 1 || mode == 3) {
                try {
                    URL aURL = new URL(url);
                    URLConnection conn = aURL.openConnection();
                    conn.setConnectTimeout(Utils.timeout);
                    conn.setReadTimeout(Utils.timeout);
                    Log.w("myApp", "doInBackground- connect");
                    conn.connect();
                    Log.w("myApp", "doInBackground- Image Request");
                    is = conn.getInputStream();
                    Log.w("myApp", "doInBackground- Image recived");
                    bm = Utils.decodeBitmapFromInputStream(is, width, width, true);
                    Log.w("myApp", "doInBackground-Decoded");

                } catch (IOException e) {
                    if (ringProgressDialog != null && ringProgressDialog.isShowing())
                        ringProgressDialog.dismiss();
                } finally {
                    try {
                        if (is != null)
                            is.close();
                    } catch (Exception e) {
                    }
                }
            } 
            return bm;
        }

InputStream is1=newbytearrayinputstream(baos.toByteArray());InputStream为2=新的ByteArrayInputStream(baos.toByteArray())这种明显不是最佳代码的原因是什么?请用ByteArrayOutputStream删除它。只需先使用InputStream inputSteam对边界进行解码。您需要从内存管理器获取大量内存。这就是它变得如此缓慢的原因。你应该告诉更多你正在做什么和你想要什么。例如,您正在下载什么类型的文件?A.jpg?png?谢谢你的输入。我已经在上面给出了更多的细节。在第二个视图中,我不得不说你的代码是正确的。如果文件只有400KB,则不需要那么多内存。但这样的话,它需要双倍的内存。加上位图的内存。
InputStream是1=newbytearrayinputstream(baos.toByteArray());InputStream为2=新的ByteArrayInputStream(baos.toByteArray())这种明显不是最佳代码的原因是什么?请用ByteArrayOutputStream删除它。只需先使用InputStream inputSteam对边界进行解码。您需要从内存管理器获取大量内存。这就是它变得如此缓慢的原因。你应该告诉更多你正在做什么和你想要什么。例如,您正在下载什么类型的文件?A.jpg?png?谢谢你的输入。我已经在上面给出了更多的细节。在第二个视图中,我不得不说你的代码是正确的。如果文件只有400KB,则不需要那么多内存。但这样的话,它需要双倍的内存。加上位图的内存。