7

I have a viewHolder that loads up an image using Picasso. The DB will return a path of URL as String. So I have my code as below (Using Kotlin)

  Picasso.with(context).load(url).error(placeholder).transform(transformation)
            .placeholder(placeholder).into(this)

It loads fine. However, sometimes the URL is empty. I'm expecting it to load the placeholder instead. But it crash out as below

java.lang.IllegalArgumentException: Path must not be empty.
    at com.squareup.picasso.Picasso.load(Picasso.java:297)

This would force me to explicitly do a check, which is not ideal

if (url == null || url.isEmpty()) {
    Picasso.with(context).load(placeholder).transform(transformation).into(this)
} else {
    Picasso.with(context).load(url).error(placeholder).transform(transformation)
            .placeholder(placeholder).into(this)
}

Is this expected that Picasso will crash when a URL String is empty instead of loading the placeholder?

Elye
  • 53,639
  • 54
  • 212
  • 474
  • Yes, it would be a lot of overhead (relatively) to load Picasso for an empty string. – zgc7009 Apr 11 '16 at 00:54
  • Wouldn't picasso handle internally where if a string is empty, or the url is inaccessible, it should fallback to the "error" or "placeholder" image? – Elye Apr 11 '16 at 01:00
  • It could, but sometimes it is just easier for libraries to assume you are going to be using the appropriate values than it is to do checks everywhere sometimessometimes. Puts some responsibility on the user. – zgc7009 Apr 11 '16 at 01:08
  • @zgc7009, when you say 'it could', perhaps you could share with me how... I would like to have that in, to eliminate the extra checks on my end. So I don't need to worry how the DB pass in value. If they are valid I'll post the image, else I'll fall back to the error image. Thanks. – Elye Apr 11 '16 at 01:10
  • No I'm saying they could design it so it does, but it isn't designed that way. You have to pass it a string. Unfortunately with programming sometimes checks are just a part of it – zgc7009 Apr 11 '16 at 01:19
  • Thanks. Facts of life. I could perhaps add Try-Catch to handle it on my end. – Elye Apr 11 '16 at 01:20

8 Answers8

6

This might be too late but i encountered this error today and after read the documentation of Picasso#load method it states that passing empty or blank string will cause the method to throw IllegalArgumentException and passing a null will not throw an exception but trigger RequestCreator#error which will load error image if one is provided otherwise the target will display nothing.

if you have no control over the image url (say its coming from server) you can try the following:

 mPicasso.load(photo.isEmpty() ? null : photo)
                .placeholder(placeholder)
                .error(error_placeholder)
                .into(target);
4

The javadoc for Picasso.load() explicitly states that it will throw an IllegalArgumentException when the URL is null or empty. So that's what you can expect.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • Thanks. Facts of life. I could perhaps add Try-Catch to handle it on my end. – Elye Apr 11 '16 at 01:20
  • It's going to be more efficient and readable if you simply check for empty or null yourself and take appropriate action. It's a very common thing to do in java. – Doug Stevenson Apr 11 '16 at 01:22
  • Cool. Like what I did above. Just thought in case there's some other error condition I might miss... since I don't have control of the DB entirely, it could be other things that could cause Picasso to throw exception. p/s: On my program, if the input is invalid, then I'll ignore it and show the placeholder image. ... By the way, I like your Kotlin blog. Cool post! – Elye Apr 11 '16 at 01:28
  • Thanks! Glad you got something out of it. :-) – Doug Stevenson Apr 11 '16 at 03:32
  • A String consisting entirely of white spaces like `" "` will also cause the exception. – Ehtesham Hasan Mar 17 '18 at 16:18
  • 1
    In fact, Passing null as a path will not trigger any request but will set a placeholder, if one is specified. Only throw IllegalArgumentException if path is empty or blank string. – Chandler Dec 10 '18 at 21:29
3

I hope it helps you:

if (item.getImagen().isEmpty()) { //url.isEmpty()
        Picasso.with(mContext)
                .load(R.drawable.placeholder)
                .placeholder(R.drawable.placeholder)
                .error(R.drawable.placeholder)
                .into(holder.imageView);

    }else{
        Picasso.with(mContext)
                .load(item.getImagen())
                .placeholder(R.drawable.placeholder)
                .error(R.drawable.placeholder)
                .into(holder.imageView); //this is your ImageView
    }
JorgeAmVF
  • 1,660
  • 3
  • 21
  • 32
Ing Rico
  • 31
  • 1
  • 1
    Try not to post answers that consist solely of code. A few lines of explanation make answers like this much easier to understand at a glance and much more liable to be upvoted/accepted. – Mike_OBrien Aug 26 '16 at 16:23
  • Its safer to use TextUtils.IsEmpty (str) then str.IsEmpty() as it checks for null rather than throwing an exception if str is null – TWI Feb 03 '17 at 10:57
  • `.equals("")` worked in my case, but, anyway, this solution is gold. – JorgeAmVF Apr 11 '19 at 00:21
2

It it late but I ran into the same problem and I solved by just passing a Uri instead of the url. just pass your url like Uri.parse(url).
It will be something like this

Picasso.with(context).load(Uri.parse(url).error(placeholder).transform(transformation)
            .placeholder(placeholder).into(this)
Reza
  • 845
  • 13
  • 18
0

I suggest you check the string before loading into Picasso.

public static boolean isBlank(String string) {
    return TextUtils.isEmpty(string.trim());
}
Faisal Shaikh
  • 3,900
  • 5
  • 40
  • 77
0

Warning: Its not enough to check the emptiness of the url String

You should trim the url String first and then do the empty check. Otherwise a String like " " can break your app.

This is how I use it.

if (imageUrl != null && imageUrl.trim().isEmpty())
{
    imageUrl = null;
}

Picasso.with(mContext)
    .load(imageUrl) // its safe to pass null, but not "" or " "
    .placeholder(R.drawable.placeholder)
    .into(mImageView);

Check the source code of Picasso to learn why.

Discussions on the topic: https://github.com/square/picasso/issues/609

Ehtesham Hasan
  • 4,133
  • 2
  • 23
  • 31
0

You can check if url is empty by using below method

if(!TextUtils.isEmpty(url.trim()) && url.trim().length >0){
    if(Patterns.WEB_URL.matcher(url).matches()){

    }
}

Source Url validation : How to check if URL is valid in Android

Madhav
  • 317
  • 2
  • 12
0

yes, picasso expects non null and non empty values so what i suggest is to use the helper TextUtils to handle this. Here an example.

String imagenUser = listaComentarios.get(position).getAvatar();
 
if (TextUtils.isEmpty(imagenUser)) {
  Toast.makeText(context, "Avatar imagenes", Toast.LENGTH_LONG).show();
  holder.imagen_usuario.setImageResource(R.mipmap.ic_launcher);
} else {
  Picasso.get()
    .load(imagenUser)
    .fit()
    .centerCrop()
    .transform(new CircleTransform())
    .into(holder.imagen_usuario);
}
Sven Eberth
  • 3,057
  • 12
  • 24
  • 29