Glide很好用很好用很好用很好用很好用。
一、原生代码加载图片
使用URLConnection配合Hanlder加载图片。
1. 申请网络权限
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true"/>
</network-security-config>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:networkSecurityConfig="@xml/network_security_config">
...
2. 定义 Handler
private Handler handler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what) {
//当获取到成功的状态码时执行
case 200:
//获取携带的bitmap
Bitmap bitmap = (Bitmap) msg.obj;
//imageView展示
imageView.setImageBitmap(bitmap);
break;
//当请求失败获取出现异常的时候回调
default:
imageView.setImageResource(R.mipmap.loader_error);
Toast.makeText(MainActivity.this, "code: " + msg.what, Toast.LENGTH_SHORT).show();
break;
}
}
};
3. 实现 loadUrlImage 方法
private void loadUrlImage(String img) {
new Thread( () -> {
Message message = new Message();
try {
//根据传入到路径生成对应的URL地址
URL url = new URL(img);
//创建链接
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
//设置请求方式
httpURLConnection.setRequestMethod("GET");
//获取返回码
int code = httpURLConnection.getResponseCode();
//当返回码为200时,表示请求成功
if (code == 200) {
//获取数据流
InputStream inputStream = httpURLConnection.getInputStream();
//利用位图工程根据数据流生成对应的位图对象
//利用message对象将生成的bitmap携带到handler
message.obj = BitmapFactory.decodeStream(inputStream);
//发送成功的状态码
message.what = 200;
} else {
//发送失败的状态码
message.what = code;
}
} catch (IOException e) {
e.printStackTrace();
//当出现异常的时候,状态码设置为 -1
message.what = -1;
} finally {
//通知handler
handler.sendMessage(message);
}
}).start();
}
4. 显示图片
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="加载图片到ImageView"
android:onClick="onLoadImageClick"/>
<ImageView
android:id="@+id/image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="TODO" />
</LinearLayout>
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.image_view);
}
public void onLoadImageClick(View view) {
//使用 HttpURLConnection 来加载网络中的图片
loadUrlImage("http://www.imooc.com/static/img/index/logo.png");
}
其实发现这样加载图片挺麻烦的。
二、使用 Glide 加载图片
当网络图片过大时,会导致我们生成的 bitmap 所占用的内存过多,从而导致 Out of Memory。同样的,当我们在加载本地资源文件中的图片时,如果图片过大,一样会导致 OOM。
这时使用 Glide 来加载图片的时候,Glide 则会帮助我们处理上面的问题
1. 环境配置
添加依赖
implementation 'com.github.bumptech.glide:glide:4.4.0'
添加权限
<uses-permission android:name="android.permission.INTERNET"/>
2. 简单使用 Glide.with()
Glide.with 会创建一个图片的实例,接收 Context、Activity、Fragment.
private void glideEasyLoadImage(String img) {
Glide.with(this)
//指定需要加载的图片资源,接收 Drawable对象、
//网络图片地址、本地图片文件、资源文件、二进制流、Uri对象等等...
.load(img)
//指定配置
//用于展示图片的ImageView
.into(imageView);
}
加载圆角图片
Glide.with(this).load(url)
//.apply(new RequestOptions().centerCrop())
.apply(new RequestOptions().transform(new CircleCrop()))
.into(imageView);
3. 配置 RequestOptions
通过 RequestOptions 对象来设置Glide的配置
private void glideLoadImage(String img) {
//通过 RequestOptions 对象来设置Glide的配置
RequestOptions options = new RequestOptions()
//设置图片变换为圆角
.circleCrop()
//设置占位图
.placeholder(R.mipmap.loading)
//设置加载失败的错误图片
.error(R.mipmap.loader_error);
Glide.with(this)
.load(img)
.apply(options)
.into(imageView);
}
4.使用 GlideApp 进行图片加载
不想每次都通过 .apply(options) 的方式来进行配置的时候,可以使用GlideApp的方式来进行全局统一的配置。
需要注意以下规则:
- 引入 repositories {mavenCentral()} 和 dependencies {annotationProcessor ‘com.github.bumptech.glide:compiler:4.8.0’}
- 集成 AppGlideModule 的类并且通过 @GlideModule 进行了注解
- 有一个使用了 @GlideExtension 注解的类 MyGlideExtension,并实现private的构造函数
- 在 MyGlideExtension 可以通过被 @GlideOption 注解了的静态方法来添加可以被GlideApp直接调用的方法,该方法默认接受第一个参数为:RequestOptions
4.1 添加依赖
dependencies {
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
}
4.2 新建类 MyAppGlideModule.java
/**
* 使用注解帮助我们生成 GlideApp 对象
*/
@GlideModule
public class MyAppGlideModule extends AppGlideModule {
}
4.3 新建类 MyGlideExtension.java
@GlideExtension
public class MyGlideExtension{
/**
* 实现private的构造函数
*/
private MyGlideExtension() {
}
//同一配置
@NonNull
@GlideOption
public static RequestOptions injectOptions(RequestOptions options) {
return options
//设置图片变换为圆角
.circleCrop()
//设置站位图
.placeholder(R.mipmap.loading)
//设置加载失败的错误图片
.error(R.mipmap.loader_error);
}
}
4.4 使用GlideApp进行图片加载
private void glideAppLoadImage (String img) {
GlideApp.with(this)
.load(img)
//调用在MyGlideExtension中实现的,被@GlideOption注解的方法,不需要传递 RequestOptions 对象
.injectOptions()
.into(imageView);
}
4.5 解决Glide找不到Android声明库问题
如果出现 错误: 程序包android.support.annotation不存在
请在导入依赖
annotationProcessor 'androidx.annotation:annotation:1.1.0'