0

Welcome

I need to download sycnronously (one at time) a lot of small remote images (between 50kb and 100kb) from a server and to store them as PNG in the device. I need to achieve this without third party libraries and I'm using this code but it is too munch slow:

        URL javaUrl = new URL(URLParser.parse(this.url));
        URLConnection connection = javaUrl.openConnection();

        InputStream input = new BufferedInputStream(javaUrl.openStream());
        ByteArrayOutputStream output = new ByteArrayOutputStream();

        byte data[] = new byte[1024];
        long total = 0;
        int count;
        while ((count = input.read(data)) != -1) {
            total += count;
            output.write(data, 0, count);
        }

        // conversion to bitmap
        InputStream in = new ByteArrayInputStream(output.toByteArray());
        Bitmap original = BitmapFactory.decodeStream(in);

        // storing bitmap as PNG file
        FileOutputStream out = new FileOutputStream(filename);
        original.compress(Bitmap.CompressFormat.PNG, 90, out);

        output.flush();
        output.close();
        input.close();
        in.close();
        original.recycle(); 

The problem is that the download is very slow. With very fast WIFI internet in the device (13MB, download speed of 1.4mbytes/s), it is taking 3-4 seconds to download the image in the device, but only 100-200ms to download the image in my PC using google chrome for example.

It is something wrong in my download algorithm? can be improved?

Thanks

NullPointerException
  • 36,107
  • 79
  • 222
  • 382
  • add them to zip file and you can download and extract from code! – Muthu Feb 20 '15 at 12:01
  • 1. Try using _BufferedInputStream_ on top of InputStream. 2. Hand BufferedInputStream directly for Bitmap.decode if you have no need to read the png data later. – harism Feb 20 '15 at 12:02
  • 1
    By one simple google query, I can find three different questions on this topic, are you sure that none of them addresses your issue? [First](http://stackoverflow.com/questions/25499868/best-way-to-download-images-on-android), [Second](http://stackoverflow.com/questions/5882005/how-to-download-image-from-any-web-page-in-java) and [Third](http://www.developerfeed.com/how-download-image-url-and-save-it-java) – Marcus Feb 20 '15 at 12:04
  • 1
    I don't think "welcome" means what you think it means. – JJJ Feb 20 '15 at 12:05
  • Harism, why should i use buffered instead normal input? i tested it and seems to be equal in speed – NullPointerException Feb 20 '15 at 15:57

1 Answers1

1

You have a totally unnecessary byte array in the middle. BitmapFactory.decodeStream() accepts an InputStream and you get an InputStream from URL.openStream().

It might not give you the speed boost you're looking for, but it'll at least get rid of a completely useless step in your code.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • Well, phone and Wifi is totally different to PC and physical cable. – Kayaman Feb 20 '15 at 12:08
  • If i use your way, Should i close and flush any input and outputs? How? – NullPointerException Feb 20 '15 at 12:16
  • Yes, you should close inputs and outputs. In the standard way. – Kayaman Feb 20 '15 at 12:22
  • How? i can't see how to do it if i use your way, URL does not have a close method – NullPointerException Feb 20 '15 at 12:24
  • Well naturally you assign the `InputStream` to a variable. You know, absolute basic Java. You don't need to flush streams before closing them either. – Kayaman Feb 20 '15 at 12:27
  • assign to a variable? you told me this: BitmapFactory.decodeStream() accepts an InputStream and you get an InputStream from URL.openStream(). so i did this: Bitmap original = BitmapFactory.decodeStream(javaUrl.openStream()); – NullPointerException Feb 20 '15 at 12:43
  • 1
    You should go through Java basics again, seems like you've missed plenty of things. `InputStream in = javaUrl.openStream(); BitmapFactory.decodeStream(in);`. That way you have the reference to the inputstream and you can close it, but you're not doing anything unnecessary in between (such as adding useless ByteArrayStreams). – Kayaman Feb 20 '15 at 12:51
  • lol i know that java basics, i was just asking because i thought you dont think that it is neccesary to close and flush in your initial asnwer – NullPointerException Feb 20 '15 at 12:59