Picasso无法从http的URL加载图片,但可以从https的URL加载图片?

3
Picasso可以正常加载HTTPS URL的图片,例如:https://i.ytimg.com/vi/28uUsJ72a1A/hqdefault.jpg。由于YouTube将所有流量都通过 HTTPS 进行转发,因此这个也可以工作:http://i.ytimg.com/vi/28uUsJ72a1A/hqdefault.jpg
但是,如果我使用自己的URL,如http://www.example.com/images/djnsdfndsf.jpg,它会将链接重定向到站点的HTTPS版本,并且只会在加载图片的时候出现错误。
这是我加载图片的方式:Picasso.with(this).load(current.getImageURL()).into(ImageView);。请注意不要删除HTML标记。
So I tried using this:
//Below code for Picasso initializing once for the app
private Picasso picasso;
private OkHttpClient okHttpClient;

okHttpClient = new OkHttpClient();
picasso = new Picasso.Builder(this)
                .downloader(new OkHttpDownloader(okHttpClient))
                .build();

//Below code to retrieve the images whereever required on the app
picasso.with(this).load(current.getImageURL()).into(imageView)

但是以上代码会提示无法解析OkHttpDownloader

目前我正在使用compile 'com.squareup.picasso:picasso:2.5.2'

编辑 如何强制Picasso使用http而不是https下载它?


1
picasso.with(this).load(current.getImageURL()).into(ImageView) 这里的 ImageView 是你的对象或类名>> - Dharmbir Singh
这是对象。 - Jake Dawsen
7个回答

9

在API 28+中不允许使用HTTP请求。如果要特别允许针对您的域名进行HTTP请求,则必须将以下文件添加到您的代码中。

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">aravind.me</domain>       
</domain-config>
</network-security-config>

将您的域名替换为 aravind.me 并将此文件添加为资源目录下的xml文件夹中的network_security_config.xml

android:networkSecurityConfig="@xml/network_security_config"

将以下内容添加到您的清单文件中的应用程序标签中。

如果可能的话,最好使用https URL。 - Shridutt Kothari

4

试试这个:

将你的URL中的http替换为https

String aUrl = aImageInfo.getImage_url().replace("http", "https");

    Picasso
            .with(myContext)
            .load(aUrl)
            .placeholder(R.mipmap.place_holder)
            .error(R.mipmap.error)
            .fit()
            .into(aHolder.aImageView);

这个不行,因为整个问题在于它被强制使用无法解析的https,我需要强制它使用http,因为我的网站没有SSL。 - Jake Dawsen
2
好的!我有点笑了,因为我在搜索Picasso库时找到了这里,然后看到了你的答案,我的想法是“好的,我不管了,这就是解决方案” :)) - sunlover3
为什么它应该工作?如果服务器重定向到https,那就没有意义了。 - Eliran Tutia
虽然这更像是一种hack,但似乎这是唯一的简单解决方案。很遗憾Picasso没有在任何地方提到它,让每个人都苦苦寻找解决方案。另一方面,Android 9,即API 28及以上版本不允许进行HTTP调用,除非在应用程序中添加新的库和更多的样板代码。此页面上有一些可能有效的建议,但我还没有尝试过它们,我只是将我的HTTP URL更改为HTTPS,对我来说运行良好。 - zeeshan

1
默认情况下,Picasso 使用 UrlConnectionDownloader。从名称中可以理解到它使用的是 HttpURLConnection,该连接不会自动从 HTTP 重定向到 HTTPS(或反之亦然)。跟随重定向可能会产生严重的安全后果。
克服这个问题的方法是使用 OkHttp3Downloader - 适用于Picasso 2的 OkHttp 3 下载器实现。
OkHttpClient client = new OkHttpClient(); 
Picasso picasso = new Picasso.Builder(context)
.downloader(new OkHttp3Downloader(client))
.build()

为了使用OkHttp3Downloader,您需要添加依赖项。
compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'

这个不再起作用了。 - Durgesh Kumar

-1

您可以将此添加到您的应用程序类中:

    final OkHttpClient client = new OkHttpClient.Builder()
            .protocols(Collections.singletonList(Protocol.HTTP_1_1))
            .build();

    final Picasso picasso = new Picasso.Builder(this)
            .downloader(new OkHttp3Downloader(client))
            .build();

    Picasso.setSingletonInstance(picasso);

-1

CustomPicasso.java

import android.content.Context;
import android.util.Log;

import com.jakewharton.picasso.OkHttp3Downloader;
import com.squareup.picasso.Picasso;

/**
 * Created by Hrishikesh Kadam on 19/12/2017
 */

public class CustomPicasso {

    private static String LOG_TAG = CustomPicasso.class.getSimpleName();
    private static boolean hasCustomPicassoSingletonInstanceSet;

    public static Picasso with(Context context) {

        if (hasCustomPicassoSingletonInstanceSet)
            return Picasso.with(context);

        try {
            Picasso.setSingletonInstance(null);
        } catch (IllegalStateException e) {
            Log.w(LOG_TAG, "-> Default singleton instance already present" +
                    " so CustomPicasso singleton cannot be set. Use CustomPicasso.getNewInstance() now.");
            return Picasso.with(context);
        }

        Picasso picasso = new Picasso.Builder(context).
                downloader(new OkHttp3Downloader(context))
                .build();

        Picasso.setSingletonInstance(picasso);
        Log.w(LOG_TAG, "-> CustomPicasso singleton set to Picasso singleton." +
                " In case if you need Picasso singleton in future then use Picasso.Builder()");
        hasCustomPicassoSingletonInstanceSet = true;

        return picasso;
    }

    public static Picasso getNewInstance(Context context) {

        Log.w(LOG_TAG, "-> Do not forget to call customPicasso.shutdown()" +
                " to avoid memory leak");

        return new Picasso.Builder(context).
                downloader(new OkHttp3Downloader(context))
                .build();
    }
}

build.gradle(模块:app)

android {

    ...

}

dependencies {

    ...

    compile 'com.squareup.picasso:picasso:2.5.2'
    compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'
}

使用方法 -

CustomPicasso.with(context)
    .load("http://i.imgur.com/DvpvklR.png")
    .into(imageView);

-1
如果您想从Picasso获得回调,请尝试以下操作,并在onBitmapLoaded()中将位图设置到您的ImageView中。
Picasso.with(getContext()).load(url).into(new Target() {
    @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        // cache is now warmed up
    }
    @Override public void onBitmapFailed(Drawable errorDrawable) { }
    @Override public void onPrepareLoad(Drawable placeHolderDrawable) { }
});

-2

如果您的URL包含Https,则必须在URL中使用https,否则它将无法加载,您也无法使用普通的http下载图像。如果您想尝试,请使用BitmapFactory下载http图像。

谢谢。


那么没有可能使用http吗? - Jake Dawsen
不,浏览器会自动将http重定向到https,但在编程中我们需要设置https。 - Jd Prajapati
你刚才说的是什么? - Odaym

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接