Glide无法加载真实图片,仅显示占位符并停留在此状态

62

我有一行非常基本的从服务器加载图片的代码:

Glide.with(view.getContext()).load(url).placeholder(R.drawable.default_profile).into(view);

出现这种情况的原因是我一直卡在了占位符被显示而不是真实图像上!

我已经确认传递的 URL 是有效且可用的。如果我不使用占位符,相同的代码可以正常工作。

Glide.with(view.getContext()).load(url).into(view);

有什么想法吗?


4
出于安全考虑,Android 不允许访问某些 URL。需要在清单文件中添加 android:usesCleartextTraffic="true"。更详细的解答请参考这里 - TeachMeJava
16个回答

104

尝试添加.dontAnimate()。 这也是由TransitionDrawable引起的,因为在滚动后没有动画,所以看起来是这样,因为它被缓存了。

正确的代码是

Glide.with(view.getContext()).load(url).placeholder(R.drawable.default_profile).dontAnimate().into(view);

我希望这对你有所帮助。


3
由于某些奇怪的原因,这解决了问题。但是没有动画过渡会显得不太美观。 - TareK Khoury
1
在Glide v4.0.0中不存在占位符。 - Mahdi
正如Glide的README.md所述,CircleImageView/CircularImageView/RoundedImageView已知在使用TransitionDrawable(.crossFade()与.thumbnail()或.placeholder())和动画GIF时存在问题,使用BitmapTransformation(.circleCrop()将在v4中提供)或.dontAnimate()来解决此问题。 - Veer

59

检查是否已在清单文件中添加了Internet权限:

<uses-permission android:name="android.permission.INTERNET"/>

Glide如果没有网络连接,不会触发异常。


7
确实!这解决了我的问题。我认为如果glide在开发者犯这样的错误时引发异常会更有用。 - Thilaw Fabrice

10
在清单文件中的应用程序标签中添加android:usesCleartextTraffic="true",并检查是否在同一清单文件中提到了Internet权限:

4

请添加以下权限以访问资源端点/网址

<uses-permission android:name="android.permission.INTERNET"/>

如果您的目标端点/ URL 只有 http,请在 manifest.xml 中添加以下代码。从 Android 9(API 级别 28)开始,默认情况下禁用明文支持。
android:usesCleartextTraffic="true"

因此,如果您从未加密的HTTP API获取资源,请不要忘记添加

res/xml/network_security_config.xml

所以代码将像这样:
网络安全配置文件 network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">urweb.id</domain>
        <domain includeSubdomains="true">localhost</domain>
        ...
        <domain includeSubdomains="true">111.222.333.444</domain>
    </domain-config>
</network-security-config>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        ...
        android:usesCleartextTraffic="true"
        ...>
    
        <activity>
        ...
        </activity>
    </application>

</manifest>

3

如果您尝试过以下步骤:

  • 在清单文件和编程文件中都已添加了INTERNET权限
  • 如果已在清单文件中添加了usesCleartextTraffic,但图像仍未加载到ImageView中

那么请尝试以下操作:

  • 在清单文件的application标签中添加以下行
android:usesCleartextTraffic="true"
  • 在你尝试执行操作的活动或片段的顶部添加以下代码
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

2
以下是我使用的一个奇怪的修复方法。
以下代码在我的情况下总是失败(12次尝试),我从未看到真正的图像:
Glide.with(context)
 .load(url)
 .asBitmap()
 .into(new SimpleTarget<Bitmap>(iconWidth, iconHeight) { ... }

以下方法始终对我有效(12次尝试) - 我总是看到真实的图像:
Glide.with(context)
 .load(url)
 .asBitmap()
 .listener(new RequestListener() {
    public boolean onException(Exception e,Object o,Target t,boolean b)
               {return false;}
    public boolean onResourceReady(Object o,Object p,Target t,boolean b,boolean c)  
               {return false;}})
 .into(new SimpleTarget<Bitmap>(iconWidth, iconHeight) { ... }

正如你所看到的,这里唯一的区别就是我增加了一个监听器。可能意义不大,但这些试验都非常仔细,所以我决定采用这种方式。


奇怪...这个对我也起作用了...有什么想法为什么会这样吗? - LifeQuestioner

2
最初的回答:以上解决方案都对我无效。问题可能出在你使用的占位符上。如果加载图像的视图具有占位符,则会导致某些问题。出于某种原因,删除该占位符似乎可以解决问题。
因此,如果您尝试膨胀(Image)View具有占位符,例如android:src =“@mipmap / placeholder”,请将其删除。
        <ImageView
            android:id="@+id/imgGallery"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:adjustViewBounds="true"
            android:scaleType="centerCrop"
            android:src="@mipmap/rugova1" />

最初的回答
像这样
 <ImageView
            android:id="@+id/imgGallery"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:adjustViewBounds="true"
            android:scaleType="centerCrop"
            />

对我来说有效。


2
使用ProgressBar作为加载动画
Glide.with(context).
        load(url)
        .listener(new RequestListener<String, GlideDrawable>() {
            @Override
            public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
                progressBar.setVisibility(View.GONE);
                return false;
            }

            @Override
            public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                progressBar.setVisibility(View.GONE);
                return false;
            }
        })
        .crossFade(1000)
        .into(imageView);

2
如果未来有人遇到此问题,您可能需要添加。
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

尽管我不确定这个变化的确切原因,但是没有这个权限我的代码无法正常工作,现在有了这个权限就可以了。


1

看起来很奇怪,但我唯一能猜到的是您的URL有效,就像您已经说过的那样。您的远程被下载后甚至应用于您的图像视图,但您的占位符某种方式将其隐藏了起来。 Glide存在一些与占位符相关的错误。

我的建议是尝试以下方法:

Glide.with(view.getContext()).load(url).
placeholder(R.drawable.default_profile).fitCenter().into(view);

因此,诀窍在于通过setImageDrawable()设置占位符,这样ImageView将像往常一样显示它,但是您明确告诉Glide使用fitCenter来适应已加载的图像并使其完美地适合ImageView的布局大小,然后通过setImageDrawable()设置它。由于适合的图像是完美的适合,因此居中会绘制覆盖整个视图区域的图像。

试试吧。


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