【问题标题】:Error HTTP 504 When load image form URL with picasso android library使用 picasso android 库加载图像表单 URL 时出现 HTTP 504 错误
【发布时间】:2020-02-14 05:59:08
【问题描述】:

我想使用 picasso android 库从 URL 加载图像并将其显示以查看,但仅在 android 7.0 Nougat 中出现错误。

图片的 URL 使用 HTTPS。在我的另一个具有相同图像 URL 的项目中,如果我在真实设备 7.0 Nougat 中运行,我没有收到错误,但如果我在模拟器 7.0 Nougat 中运行,它仍然会出错。

我尝试使用来自不同域的其他 URL 图片,但我也没有收到错误。

我该如何解决?

Picasso.get().load("My_URL_Image")
                .resize(200,200)
                .centerInside()
                .placeholder(R.drawable.ic_default)
                .error(R.drawable.ic_default)
                .into(holder.imageView, object : Callback{
                    override fun onSuccess() {}

                    override fun onError(e: Exception?) {
                        e?.printStackTrace()
                    }

                })
W/System.err: com.squareup.picasso.NetworkRequestHandler$ResponseException: HTTP 504
W/System.err:     at com.squareup.picasso.NetworkRequestHandler.load(NetworkRequestHandler.java:51)
W/System.err:     at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:219)
W/System.err:     at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:175)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:761)
        at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:354)

【问题讨论】:

  • 504 是超时错误。您是否检查过此错误是否出现在其他模拟器中?
  • 我在真实设备 7.0 Nougat (Xiaomi) 上运行,但仍然出现该错误
  • 我阅读并尝试过,但没有成功。这和图片网址域有关系吗?

标签: java android kotlin picasso


【解决方案1】:

您必须在您的AndroidManifest.xml 文件中设置一个networkSecurityConfig,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:networkSecurityConfig="@xml/network_security_config">




    </application>
</manifest>

之后,在您的 xml 文件夹中,您将根据上述代码提及名称 network_security_config 创建新文件,以启用所有不加密的请求:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

现在您的应用将对任何类型的连接发出所有请求。更多信息请阅读this

希望对你有帮助....!

【讨论】:

  • 对我没有帮助
  • 这是对我有用的解决方案。谢谢! (不过我只会将它用于我的实验项目)
  • @Benny,你为什么只将它用于你的实验项目?这种方法有缺点吗?
  • @austinw 我现在只将它用于我的实验项目,因为我没有花时间调查允许任何类型的不加密连接所涉及的安全风险。
【解决方案2】:

维护一个具有低 minSdkVersion 的旧应用程序,我也不确定明文对我应用程序的其余 API 的影响有多深,因此我更喜欢使用为 Picasso 定制的 OkHttpClient 的方法。

版本:

  • OkHttp: 3.10.0
  • 毕加索:2.71828
    public static OkHttpClient getUnsafeOkHttpClient() {
        try {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[] {
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[]{};
                        }
                    }
            };

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });

            OkHttpClient okHttpClient = builder.build();
            return okHttpClient;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void loadLogo(String url) {
        if (url != null && !url.isEmpty()) {
            OkHttpClient picassoClient = getUnsafeOkHttpClient();
            Picasso picasso = new Picasso.Builder(this).downloader(new OkHttp3Downloader(picassoClient)).build();
            picasso.setLoggingEnabled(true);
            picasso.load(url)
                    .placeholder(R.drawable.default_logo)
                    .error(R.drawable.default_logo)
                    .into(titleIV);
        }
    }

【讨论】:

  • 很好的解决方案!!它帮助我发送带有 ("Accept", "image/jpg") 和 ("Content-Type", "image/jpg") 标头的请求。如何使用标头设置客户端:stackoverflow.com/questions/35728484/…
【解决方案3】:

504 是超时错误代码意味着您(客户端)正在连接的服务器的上游服务器没有收到来自上游另一台服务器的“及时”响应

=> 尝试通过模拟器检查您的互联网连接

【讨论】:

  • 我的互联网连接工作正常,因为我的应用程序使用互联网连接来请求服务器
  • 但是您得到的代码显示连接超时,这意味着您的互联网或服务器已关闭或在时间限制内没有响应
【解决方案4】:

我将上面的代码更改为此代码,因为当我将其复制到我的 android studio 时 它有几个错误,我不得不更改代码的某些部分,但效果很好。

我也在使用“zampp”服务器

public  okhttp3.OkHttpClient getUnsafeOkHttpClient() {
    try {
        // Create a trust manager that does not validate certificate chains
        final TrustManager[] trustAllCerts = new TrustManager[] {
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    @Override
                    public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return new java.security.cert.X509Certificate[]{};
                    }
                }
        };

        // Install the all-trusting trust manager
        final SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

        // Create an ssl socket factory with our all-trusting manager
        final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

        okhttp3.OkHttpClient.Builder builder = new okhttp3.OkHttpClient.Builder();
        builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]);
        builder.hostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });

        okhttp3.OkHttpClient okHttpClient = builder.build();
        return okHttpClient;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

public void loadLogo(String url) {
    ImageView imageView = findViewById(R.id.imageView);
    if (url != null && !url.isEmpty()) {
        OkHttpClient picassoClient = getUnsafeOkHttpClient();
        Picasso picasso = new Picasso.Builder(this).downloader(new OkHttp3Downloader((Call.Factory) picassoClient)).build();
        picasso.setLoggingEnabled(true);
        picasso.load(url)
                .into(imageView);
    }
}

那么你应该把它添加到android studio的onCreate方法中:

  getUnsafeOkHttpClient();
  loadLogo(imageUri);

【讨论】:

    【解决方案5】:

    感谢大家的帮助,我找到了解决这种情况的方法,我在我的主页活动中删除了FirebaseFirestore.getInstance(),因为我不再在主页上使用 firebase。我不知道为什么,但如果我不删除主页中的代码,应用程序在真实设备 android 7.0 Nougat 中运行正常,但在模拟器 7.0 Nougat 中仍然出错。

    【讨论】:

    • 我认为这不是正确的答案。我面临这个问题,我什至没有在我的项目中使用 Firebase。
    • 这不是这个问题的正确解决方案
    猜你喜欢
    • 2021-07-18
    • 2018-07-14
    • 2022-08-21
    • 1970-01-01
    • 2020-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    相关资源
    最近更新 更多