0

I am trying to convert a URL to Base64 in Kotlin. I am using Apache Commons IO to accomplish this by first converting the URL to a ByteArray:

val imageBytes = IOUtils.toByteArray(URL(url))

This line creates a android.os.NetworkOnMainThreadException error when I run my app. How do I resolve this? I don't want to change the ThreadPolicy to bypass the error. Below the above line of code, I also have the following:

val imageBase64 = Base64.encode(imageBytes, Base64.URL_SAFE and Base64.NO_WRAP)

val item = ItemCard(
    imageBase64,
    label,
    total
)

list += item

The entire code block is in a loop. So I would also need something where I can get the result in a timely manner where it doesn't interfere with the actual Base64 encoding.

Tom Darious
  • 434
  • 6
  • 18
  • 1
    Why would you want to convert a URL to base64? Base64 is a hack that's used to pass binary data over a text only channel, such as inside a URL. You wouldn't convert something already text like a URL into base 64. – Gabe Sechan May 30 '22 at 23:34
  • I'd agree. The exact duplicate is not so great (outdated), better see the second one... and pass binary data. – Martin Zeitler May 30 '22 at 23:43
  • @GabeSechan The URL is actually an image URL. The image URL has an expiry date, meaning it's only valid for a certain period of time. If I cache the current image URL, it won't always be valid. That's why I'm trying to convert the image URL to Base64 before the link is invalid so I can cache the Base64 encoding. – Tom Darious May 30 '22 at 23:57
  • That doesn't make any sense. The Base64 encoding of it will still have the timestamp in it if its embedded. And it it isn't and you're just saving the URL, you can do that without encoding it. The encoding gains you nothing. And if you're talking about caching the image itself, it makes even less sense to use base64 when caching on device, as you'd be saving it to the filesystem and then converting it in memory in the future, making your app less efficient without any gain – Gabe Sechan May 30 '22 at 23:59
  • @GabeSechan That's not correct, I have tried converting the image URL to Base64 and it worked. The expiry time for the URL is an hour and the Base64 encoding was still valid after an hour. – Tom Darious May 31 '22 at 00:23
  • WHere are you saving it in a cache? Because data is data. Converting it to base 64 will have no effect on a timeout on a cache. I don't think you know what you're actually doing. – Gabe Sechan May 31 '22 at 01:16
  • @GabeSechan Well I'm not saving directly into the cache. I'm saving the data on my Firebase Realtime Database. For loading the image, I'm using Glide. – Tom Darious May 31 '22 at 02:44
  • Looked up IOUtils. It's not saving the URL. IOUtils.toByteArray actually fetches the URL's image and returns it. So you're base64ing the actual data. Which also means any cache timeout on the URL will not be respected, because you're storing the actual data in the db, not a URL to be used later. And the data should only be base64ed if the db you're storing it in doesn't have a binary data option (which firebase doesn't). – Gabe Sechan May 31 '22 at 03:08
  • That also explains why there's a networking function called there- you're fetching the URL. – Gabe Sechan May 31 '22 at 03:10

0 Answers0