Android 图片加载框架:Picasso vs Glide
引言在 Android 开辟中,图片加载是移动应用的核心功能之一。合理选择图片加载框架不仅能提拔用户体验,还能优化内存管理和应用性能。本文将深入对比 Picasso 和 Glide 两大主流框架,联合代码示例分析它们的差异、工作原理及优化计谋。
1. 架构计划
特性PicassoGlide库巨细118KB(轻量级)430KB(功能丰富)动态图支持仅表现 GIF 首帧原生支持 GIF/WebP/APNG缓存计谋全尺寸缓存按尺寸缓存 + 智能计谋生命周期需手动管理自动绑定 Activity/Fragment
1. 库的巨细
[*]Picasso:在小型项目里,对应用体积的严格控制是关键考量。Picasso 的小巧特性使其成为这类项目的理想选择,由于它不会给应用带来过多的额外负担。比方,对于一些简朴的工具类应用,开辟者希望在实现根本图片展示功能的同时,保持应用的轻量级,Picasso 就可以或许很好地满足这一需求。
[*]Glide:虽然 Glide 的库体积相对较大,但它丰富的功能为大型项目提供了强大的支持。在电商、社交等大型应用中,必要处理惩罚大量不同格式的图片,并且要实现复杂的图片加载结果,如图片预加载、缩略图展示等,Glide 的这些功能可以极大地提拔用户体验,因此多占用一些 APK 空间也是值得的。
2. 支持的图片格式
[*]Picasso:由于对 GIF 和 WebP 等动态图片格式支持不佳,在必要展示动态图片的场景下会受到很大限定。好比在社交应用中,用户大概会发送 GIF 动图来表达感情,使用 Picasso 就无法很好地实现这一功能。
[*]Glide:对多种动态图片格式的支持使得它在处理惩罚各种类型的图片时更加灵活。在娱乐、社交等应用中,经常会有展示 GIF、WebP 动图的需求,Glide 可以轻松应对,为用户提供丰富的视觉体验。而且,对 AVIF 格式的硬件解码优化,能让图片在保证高质量的同时,减少加载时间和流量斲丧。
3. 缓存计谋
[*]Picasso:只缓存全尺寸图片的计谋在必要不同尺寸图片时会带来性能标题。比方,在一个图片列表中,每个图片的表现尺寸大概不同,如果使用 Picasso,每次表现不同尺寸的图片都要重新从全尺寸图片举行裁剪,这会增加 CPU 的盘算负担和内存占用,导致应用的流畅度下降。
[*]Glide:按尺寸缓存的计谋可以根据不同的需求直接从缓存中获取合适尺寸的图片,避免了重复的裁剪使用,提高了图片加载的效率。在一些必要频繁切换图片尺寸的应用中,如图片欣赏器,Glide 的这种缓存计谋上风显着。
4. 生命周期管理
[*]Picasso:不完善的生命周期管理必要开辟者手动处理惩罚图片加载的停息和恢复,这增加了开辟的复杂度,并且容易出现遗漏导致内存走漏。比方,在 Activity 销毁时,如果没有手动取消正在举行的图片加载任务,这些任务大概会继续占用内存,造成内存走漏,影相应用的稳固性。
[*]Glide:自动与 Activity 和 Fragment 的生命周期绑定,开辟者无需手动干预,减少了开辟工作量,同时也降低了内存走漏的风险。在应用的页面切换过程中,Glide 会自动处理惩罚图片加载任务的停息和取消,保证了应用的性能和稳固性。
5. API 简洁性
[*]Picasso:简洁的 API 使得开辟者可以快速实现根本的图片加载功能,适合在项目的快速原型开辟阶段使用。在项目初期,开辟者必要快速验证想法,Picasso 的简朴易用可以帮助他们在短时间内搭建出具有图片展示功能的原型。
[*]Glide:虽然 API 相对复杂,但丰富的配置选项为开辟者提供了更多的灵活性。在必要实现复杂图片加载结果的项目中,如图片的渐变加载、不同的缩放方式等,Glide 的强大功能可以满足这些需求。
1. 根本图片加载
Picasso
import android.os.Bundle;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import com.squareup.picasso.Picasso;
public class PicassoActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView{"name":"GodelPlugin","parameters":{"input":"\"setContentView(R.layout.activity_main);\""}}<|FunctionExecuteEnd|><|FunctionExecuteResult|>setContentView(R.layout.activity_main);<|FunctionExecuteResultEnd|>
ImageView imageView = findViewById(R.id.imageView);
String imageUrl = "https://example.com/image.jpg";
Picasso.get()
.load(imageUrl)
.into(imageView);
}
} Glide
import android.os.Bundle;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import com.bumptech.glide.Glide;
public class GlideActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView{"name":"GodelPlugin","parameters":{"input":"\"setContentView(R.layout.activity_main);\""}}<|FunctionExecuteEnd|><|FunctionExecuteResult|>setContentView(R.layout.activity_main);<|FunctionExecuteResultEnd|>
ImageView imageView = findViewById(R.id.imageView);
String imageUrl = "https://example.com/image.jpg";
Glide.with(this)
.load(imageUrl)
.into(imageView);
}
} 从上述代码可以看出,二者根本的图片加载方式都是链式调用,语法较为相似。不过 Picasso 使用 Picasso.get() 获取实例,Glide 使用 Glide.with(context) 绑定上下文。
GIF 加载对比
// Picasso(仅显示首帧)
Picasso.get().load(gifUrl).into(imageView);
// Glide(完整动画支持)
Glide.with(context)
.asGif()
.load(gifUrl)
.placeholder(R.drawable.loading)
.error(R.drawable.error)
.into(imageView); 缓存计谋
Picasso
Picasso 只缓存全尺寸图片,以下是简朴使用示例。
import android.os.Bundle;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import com.squareup.picasso.Picasso;
public class PicassoCacheActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView{"name":"GodelPlugin","parameters":{"input":"\"setContentView(R.layout.activity_main);\""}}<|FunctionExecuteEnd|><|FunctionExecuteResult|>setContentView(R.layout.activity_main);<|FunctionExecuteResultEnd|>
ImageView imageView = findViewById(R.id.imageView);
String imageUrl = "https://example.com/image.jpg";
Picasso.get()
.load(imageUrl)
.into(imageView);
}
} Glide
Glide 支持按尺寸缓存,并且可以自界说缓存计谋。
import android.os.Bundle;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
public class GlideCacheActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView{"name":"GodelPlugin","parameters":{"input":"\"setContentView(R.layout.activity_main);\""}}<|FunctionExecuteEnd|><|FunctionExecuteResult|>setContentView(R.layout.activity_main);<|FunctionExecuteResultEnd|>
ImageView imageView = findViewById(R.id.imageView);
String imageUrl = "https://example.com/image.jpg";
Glide.with(this)
.load(imageUrl)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
}
}
在上述 Glide 代码中,DiskCacheStrategy.ALL 表示同时缓存原始图片和处理惩罚后的图片。
生命周期管理
Picasso
Picasso 必要开辟者手动管理生命周期,否则大概会出现内存走漏。以下是一个简朴的在 Activity 销毁时取消请求的示例。
import android.os.Bundle;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import com.squareup.picasso.Picasso;
public class PicassoLifecycleActivity extends AppCompatActivity {
private ImageView imageView;
private String imageUrl = "https://example.com/image.jpg";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView{"name":"GodelPlugin","parameters":{"input":"\"setContentView(R.layout.activity_main);\""}}<|FunctionExecuteEnd|><|FunctionExecuteResult|>setContentView(R.layout.activity_main);<|FunctionExecuteResultEnd|>
imageView = findViewById(R.id.imageView);
Picasso.get()
.load(imageUrl)
.into(imageView);
}
@Override
protected void onDestroy() {
super.onDestroy();
Picasso.get().cancelRequest(imageView);
}
} Glide
Glide 会自动绑定 Activity 或 Fragment 的生命周期。
import android.os.Bundle;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import com.bumptech.glide.Glide;
public class GlideLifecycleActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView{"name":"GodelPlugin","parameters":{"input":"\"setContentView(R.layout.activity_main);\""}}<|FunctionExecuteEnd|><|FunctionExecuteResult|>setContentView(R.layout.activity_main);<|FunctionExecuteResultEnd|>
ImageView imageView = findViewById(R.id.imageView);
String imageUrl = "https://example.com/image.jpg";
Glide.with(this)
.load(imageUrl)
.into(imageView);
}
} 工作原理的扩展解释
Picasso
[*]请求构建:通过链式调用的方式构建图片请求,这种方式简洁直观,开辟者可以很方便地指定图片的来源(如网络 URL、本地文件等)和要表现的 ImageView。比方,Picasso.with(context).load(url).into(imageView)这行代码就完成了从指定 URL 加载图片并表现在 ImageView 上的根本请求构建。
[*]缓存查找:内存缓存是为了快速获取最近使用过的图片,减少加载时间。当内存缓存未命中时,再去磁盘缓存中查找,磁盘缓存可以存储更多的图片,但查找速度相对较慢。这种两级缓存机制可以在一定程度上提高图片加载的效率。
[*]网络请求:如果缓存中都没有找到图片,Picasso 会使用 OkHttp(默认)或其他网络库发起网络请求下载图片。在下载过程中,大概会受到网络状况的影响,如网络耽误、丢包等。
[*]图片处理惩罚:下载完成后,Picasso 会将图片存入缓存,以便后续使用。同时,将图片表现在 ImageView 上,大概会根据 ImageView 的尺寸对图片举行裁剪或缩放处理惩罚。
https://i-blog.csdnimg.cn/direct/2395bd32c4ad44419e9130fb3639e646.png
Glide
[*]请求构建:使用链式调用构建请求,并且可以通过apply(options)方法对图片加载举行各种配置。比方,可以设置图片的缩放方式、占位图、错误图等。这种灵活的配置方式可以满足不同场景下的需求。
[*]缓存查找:Glide 的内存缓存分为弱引用缓存和 LruResourceCache。弱引用缓存可以在系统内存不敷时自动释放,而 LruResourceCache 则接纳最近最少使用(LRU)算法来管理缓存,优先保留最近使用的图片。磁盘缓存同样可以根据不同的计谋举行管理,如只缓存原始图片、只缓存处理惩罚后的图片或都缓存等。
[*]资源解码:当磁盘缓存未命中时,Glide 会根据图片的来源获取原始数据,并举行解码。在解码过程中,会根据配置举行尺寸调整、格式转换等使用。比方,如果必要将图片转换为 WebP 格式以减少体积,Glide 可以在解码时完成这个使用。
[*]图片表现:解码完成后,将图片存入缓存并表现在 ImageView 上。同时,Glide 会根据 Activity 或 Fragment 的生命周期管理图片加载任务,确保在页面不可见时停息或取消加载任务,避免资源浪费。
https://i-blog.csdnimg.cn/direct/9ebec4ae7eda4652a8f600c79599efe9.png
优化发起的扩展解释
Picasso
[*]内存缓存优化:通过Picasso.Builder自界说内存缓存巨细,可以根据应用的实际需求合理分配内存。如果应用中必要处理惩罚大量的图片,并且装备内存充足,可以得当增大内存缓存的巨细,以提高图片加载的速度。比方,将内存缓存设置为 5MB,可以缓存更多的图片,减少从磁盘缓存或网络加载图片的次数。
[*]图片裁剪:在加载图片时指定 ImageView 的尺寸,可以避免加载过大的图片浪费内存。比方,在一个图片列表中,每个图片的表现尺寸是固定的,如果不指定尺寸,Picasso 大概会加载全尺寸的图片,然后再举行裁剪,这会占用大量的内存。通过resize(width, height).centerCrop()方法可以直接加载合适尺寸的图片,减少内存占用。
Glide
[*]磁盘缓存优化:通过DiskCacheStrategy自界说磁盘缓存计谋,可以根据应用的需求选择合适的缓存方式。比方,DiskCacheStrategy.ALL表示缓存原始图片和处理惩罚后的图片,如许在下次必要雷同图片时,可以直接从缓存中获取,提高加载速度。而DiskCacheStrategy.NONE则表示不举行磁盘缓存,实用于一些暂时图片或不希望占用磁盘空间的场景。
[*]图片变换:合理使用Transformation对图片举行裁剪、圆角处理惩罚等使用,可以减少内存占用。比方,在表现圆形头像时,使用CircleCrop变换可以直接将图片裁剪成圆形,避免加载完整的方形图片后再举行裁剪,从而减少内存斲丧。
[*]预加载:对于一些大概会用到的图片,提前举行预加载可以提高用户体验。比方,在一个图片列表中,当用户滚动到某一位置时,提前预加载后续大概会表现的图片,当用户滚动到这些图片时,就可以直接从缓存中加载,减少等候时间。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]