Rishab Parmar
Rishab Parmar

Reputation: 419

Malformed URL Exception in Android

I'm encountering the following error when passing the URL which is stored as a string in an array: java.net.MalformedURLException: no protocol: "http://cdn.posh24.se/images/:profile/022439100375d87ad153ed7038a3d2ba6"

I have saved the url in a String array imageURLs[] that store the URL as a String. When I pasted the link directly, downloadImage.execute("http://cdn.posh24.se/images/:profile/022439100375d87ad153ed7038a3d2ba6").get(), works flawlessly. But when I pass in the array reference to the URL, for example: execute(imageURLs[0]).get(), it throws me the above mentioned error.

The code to download the Bitmap from the net:

public class DownloadCelebImage extends AsyncTask<String, Void, Bitmap> {
        Bitmap resultImage;

        @Override
        protected Bitmap doInBackground(String... urls) {
            try {
                URL imageURL = new URL(urls[0]);
                HttpURLConnection httpURLConnection = (HttpURLConnection) imageURL.openConnection();
                InputStream inputStream = httpURLConnection.getInputStream();
                resultImage = BitmapFactory.decodeStream(inputStream);
                return resultImage;
            } catch (Exception e) {
                e.printStackTrace();                  
                return resultImage;
            }
        }
    }

The method call:

DownloadCelebImage downloadImage = new DownloadCelebImage();
        Bitmap fetchedCelebMugshot = null;
        int randomCelebIndex = getRandomCelebrity();
        try {
            String url = profileArray[randomCelebIndex][0];
            fetchedCelebMugshot = downloadImage.execute(url).get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

Note that, profileArray[randomCelebIndex][0] contains the link ("http://cdn.posh24.se/images/:profile/022439100375d87ad153ed7038a3d2ba6") to download the image. It raises the exception on execute(url).get().

EDIT

Check the correct solution in the comment of the answer below. It has been explained over there.

Upvotes: 0

Views: 2528

Answers (1)

Stephen C
Stephen C

Reputation: 719561

The URL that you are using:

  http://cdn.posh24.se/images/:profile/022439100375d87ad153ed7038a3d2ba6

contains a : in the path. The : character is a reserved character, and should be %-escaped. A corrected version of the URL is

  http://cdn.posh24.se/images/%3Aprofile/022439100375d87ad153ed7038a3d2ba6

I don't know if the unescaped : would cause the problem you are experiencing. In fact, I can't reproduce the exception with Java(tm). So I suspect that this isn't the real problem.


You say:

When I pasted the link directly,

downloadImage.execute("http://cdn.posh24.se/images/:profile/022439100375d87ad153ed7038a3d2ba6").get()

it works flawlessly. But when I pass in the array reference to the URL, for example:

execute(imageURLs[0]).get(), 

it throws me the above mentioned error.

If we take what you say at face value, then there is only one logical explanation: imageURLs[0] does not contain that string at the point that it is used.

I know you said it does ... but it can't.

So what could be going one here?

  • You could simply be mistaken. (It happens)
  • It could be that URLs look like they are the same, but are subtly different. (Read about homoglyphs.)
  • This could be a problem caused by inadequate synchronization. I think this is the most likely explanation.

If one thread is populating the imageURLs array and another thread is reading is AND the two thread are not synchronizing properly, then it is possible that the reading thread does not see correct value. There are a couple of scenarios:

  • The reading thread could be reading the array cell too soon.
  • The writing thread (or another thread) could be overwriting the array cell, and the reading thread could be picking up the wrong version
  • This could be a memory anomaly; e.g. due to the write to the array cell not being flushed to memory. Java will only insert a memory barrier (e.g. cache flush instructions) at a synchronization point. (Technically when there is a happens before relationship ... which covers other cases as well.)

Note that running the application with a debugger is liable to change the behavior of the program and/or show different values in the array than the reader thread is seeing. Any evidence provided by the debugger should be treated with suspicion.


I suspect that the only way we can get to the bottom of this is if you write a complete minimal reproducible example that other people can run and observe the behavior that you are seeing.

Upvotes: 3

Related Questions