前言

在上一篇文章中,我们讲解了如何加载本地图片,那么在实际项目中 ImageView 大多数使用场景是加载网络图片,网络图片其实就是存储在服务器上的文件,我们需要从服务器获取到文件的二进制输入流 Inpustream ,然后将其转化为 ImageView 可以加载的 Bitmap 对象。实现网络图片的加载。

这篇文章我们通过使用原始的网络连接和使用第三库来简单讲解 ImageView 网络图片的加载。

怎么使用原始方式加载网络图片?

第三方网络图片加载库与原始加载库的对比?

怎样使用第三方网络加载库加载图片?

使用原始方式加载网络图片

先上代码(主要分为三大步骤):

1~6 : 从网络获取图片。由于Android 系统规定网络请求操作需要在子线程完成。主要是因为网络请求属于耗时操作,如果在主线程发起网络请求会导致主线程在网络请求期间,无法及时响应用户的操作,

7:利用在 Activity声明的 Handler对象把在子线从网络获取到的 Bitmap 对象,转移到 UI 线程。

8 : 更新UI。

public class ImageNetActivity extends AppCompatActivity {

/**

* 7.要知道 这里现在是子线程 更新UI的操作需要在主线程(UI线程)完成。

* 在 Activity 中声明 Handler 对象,并复写它的 handleMessage 方法

*/

private Handler mHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

if (msg.what == 1010) {

Bitmap bitmap = (Bitmap) msg.obj;

setImageView(bitmap);

}

}

};

private ImageView mImageView;

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_image_net);

mImageView = findViewById(R.id.image);

loadImageUrl("https://cdn.pixabay.com/photo/2017/05/09/23/02/dog-2299482_960_720.jpg");

}

private void loadImageUrl(final String imageUrl) {

// Android 系统强制网络请求需要在子线程操作

new Thread(new Runnable() {

@Override

public void run() {

InputStream inputStream = null;

try {

// 1. 把传过来的路径转成URL

URL url = new URL(imageUrl);

// 2.通过URL 建立网络连接

// --> url.openConnection() 返回 URLConnection

// ,它是一个抽象类,这里需要通过Http协议建立连接,需要它的实现类 HttpURLConnection

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

// 3. 使用GET方法访问网络

urlConnection.setRequestMethod("GET");

// 配置网络超时时间为 10秒

urlConnection.setConnectTimeout(10000);

//4. 获取Http协议 响应码

int responseCode = urlConnection.getResponseCode();

// Http 协议 规定 响应码为200时 请求成功

if (responseCode == 200) {

// 5. 得知 请求资源成功后,获取图片文件输入流

inputStream = urlConnection.getInputStream();

// 6. 把获取到的 文件输入流 通过 系统Api 转换为 ImageView 可以识别的 Bitmap 对象

Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

// 7.要知道 这里现在是子线程 更新UI的操作需要再主线程(UI线程)完成。

Message message = mHandler.obtainMessage();

message.obj = bitmap;

message.what = 1010;//

mHandler.sendMessage(message);

}

} catch (IOException e) {

e.printStackTrace();

} finally {

if (inputStream != null) {

try {

//关闭流

inputStream.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}).start();

}

}

/**

* 8.利用从 Mesage 从子线程中携带回来的 Bitmap 对象,在UI线程设置图片

*/

private void setImageView(Bitmap bitmap) {

mImageView.setImageBitmap(bitmap);

}

}

上面是创建一个空的 Activity ,布局文件中只有一个 ImageView 控件。

注意:在 Android中 主线程 也叫 UI线程。UI 线程是响应用户操作的线程,一旦在 UI线程中存在好在操作,就会阻塞 UI 线程,导致无法及时响应用户操作事件。所以在Android 系统 4.0 后,强制网络请求操作必须在子线程。但问题是:所有更新 UI 的操作又必须在UI线程,这就是我们必须把网络请求的结果,转移到主线程才能更新 UI。怎么转移呢? 那就是 Handler。这个现在知道怎么用就行,后面我们会仔细讲解。

上面的代码中,利用系统自带 ULRConnection请求网络请求的步骤注释已经很详细了。可仔细了解其网络请求步骤,大致的套路是一样的。

特别特别特别注意:网络请求是需要权限的,你需要在 AndroidManifet.xml 文件中声明一句用户权限。至于权限的概念后面我们会细聊。现在只需要在AndroidManifet.xml文件申明即可。

第三方网络图片加载库与原始加载库的对比

我们来思考几个问题,如果在真实项目中,我们这样加载图片你觉得可以吗?

........

答案是:不可以。

问题1:上面就只单一使用了内存缓存来解决图片加载问题,Android 系统为每个应用分配的内存是有限的,假如说我们的图片成千上万,即使现在的 Android 手机硬件都配置很高,也顶不住这样的操作,当内存不足时应用马上会崩溃(Crash)。

问题2:内存缓存,易失去性。即当你重新启动应用程序后,原来已经加载过的图片就会丢失,重启后又会重新下载!这就会导致页面加载缓慢,再次耗费用户流量。

所以我们需要一个比较完善的图片加载系统,这个系统最基础的要包括图片的缓存策略:先从网络请求图片,在手机内存中和SD卡中各自保存一份图片资源。当重启应用时,如果图片存在SD卡中,就可以从SD卡中直接获取图片加载。并且SD卡所能存储的图片总数是一定的,会不断的根据策略去舍去图片的存留。

还有非常重要的一点:从图片加载库的使用者角度讲,使用者无需关心内部到底是使用内存缓存,还是SD卡缓存,或是直接从网络获取的。这对于使用者来讲,内部的一切用户并不需要知道。使用者只需要知道加载图片的接口。

对于图片加载框架,内部实现是极其复杂的,目前我们并不需要了解其内部实现方式。

下面我们就使用最常用的图片加载框架 Glide来完成我们图片加载框架使用的演示。

怎样使用第三方网络加载库加载图片(Glide)

我们要知道,因为Android是开源的,所以会产生各种各样的第三方框架,而我们不能盲目的去使用,要根据实际情况,从这之中挑选出最优的、最适合自己项目的框架,合理有效的去使用各种资源。而我们推荐的Glide是经过不断的和其他框架对比所挑选出来性价比最高的!

目前国内主流的第三方网络图片加载库有Glide(主推)、ImageLoader、Picasso、Volley、Fresco等,感兴趣的小伙伴可以去搜索一下这些加载库的全方面对比,百度一哈比比皆是,我们就不再这里将网上的一些大神所对比的实际内容再复述一遍啦。下面请跟我走4步,完成你人生中第一次加载网络图片吧!!!

首先我们要通过依赖 Glide 图片加载库。

在官方文档中我们找到需要依赖的 Glide库地址。

implementation 'com.github.bumptech.glide:glide:4.9.0'

将依赖地址放置到 app 模块下的 build.gradle 中如图:

添加完成后,我们点击 右上角的 Sync Now ,从网络下载依赖库到本地,并依赖到 app 模块。

我们在创建的空 Activity 当中,为 ImageView控件利用 Glide加载图片。

okay,搞定!!使用第三图片加载库是不是很简单。

其实里面的大致操作就是我们在第一个问题中书写的代码,里面多的就是各种缓存策略和逻辑处理。

结语

关于网络图片的加载我们今天就讲到这里,请原谅小编没有对Glide的源码做详解,因为内容过于复杂,涉及到很多初学者无法理解的知识,咱们目前只需要会使用,慢慢的跟着我们一起学习,后续这些都会融会贯通的~ 如果有小伙伴对Glide的源码感兴趣可以加入我们的微信群一起探讨~ 在公众号中回复微信群,就可以加入其中,也可以在公众号中回复视频,里面有一些初学者视频哦~

PS:如果还有未看懂的小伙伴,欢迎加入我们的QQ技术交流群:892271582,里面有各种大神回答小伙伴们遇到的问题,我们的微信群马上也将要和大家见面啦,届时希望大家踊跃加入其中~~

android显示网络图片控件,Android控件之ImageView(二)相关推荐

  1. android显示多个网络图片不显示,Android显示网络图片实例

    本文实例讲述了Android显示网络图片的方法,分享给大家供大家参考.具体方法如下: 一般来说,在Android中显示一张网络图片其实是非常简单的,下面就是一个非常简单的例子: 步骤1: ① 创建你的 ...

  2. Android显示日历的函数,android实现双日期选择控件(可隐藏日,只显示年月)

    在安卓开发中,会碰到选开始日期和结束日期的问题.特别是在使用Pad时,如果弹出一个Dialog,能够同时选择开始日期和结束日期,那将是极好的.我在开发中在DatePickerDialog的基础上做了修 ...

  3. android 显示天气插件下载,Android天气插件

    Android天气插件 天气插件Android SDK,包括实况天气.空气质量.灾害预警.生活指数等天气内容,支持在Android应用任意位置加入天气内容,并可生成天气频道页面. 下载 # 适配版本 ...

  4. android显示图片部分区域,Android编程实现只显示图片一部分的方法

    本文实例讲述了Android编程实现只显示图片一部分的方法.分享给大家供大家参考,具体如下: 在Android应用程序中加载一张图片,然后把它显示出来这是一件非常容易的事情,那怎么才能显示一张图片的一 ...

  5. android 显示图片和文字,android TextView显示文字和图片

    在做web的时候jsp页面可以直接显示一段html代码,如: TextView使用HTML 强调 斜体 " +" 超链接HTML入门学习HTML! 颜色1" +" ...

  6. android显示矩阵大小,关于android:显示代表灰度图像的双值矩阵

    我的问题是:我有一个字节数组,必须与ImageView一起显示. 这是我的代码: @Override protected void onCreate(Bundle savedInstanceState ...

  7. android显示通知图标大全,Android推送通知:图标未显示在通知中,而是显示白色方块...

    Android推送通知:图标未显示在通知中,而是显示白色方块 我的应用会生成通知,但我没有显示为该通知设置的图标.相反,我得到一个白色方块. 我已经尝试调整图标的大小(尺寸720x720,66x66, ...

  8. android显示输入法键盘布局,android 解决输入法键盘遮盖布局问题

    这里采用滚动布局来解决输入法遮盖布局的问题,方法如下: /** * @param root 最外层布局,需要调整的布局 * @param scrollToView 被键盘遮挡的scrollToView ...

  9. android 显示进度,progressdialog-如何在Android中显示进度对话框?

    progressdialog-如何在Android中显示进度对话框? 当我单击"登录"按钮时,我想显示ProgressDialog,这需要时间才能移动到另一个页面. 我怎样才能做到 ...

最新文章

  1. video怎么重新加载 vue_vue.js中vue-video-player中的怎么插入多个视频,视频可以同时播放的问题及解决办法...
  2. [攻克存储] 掌握SDRAM/DDR的结构与寻址
  3. python 画三维函数图-Python画三维图-----插值平滑数据
  4. java数据类型怎样理解_深入理解Java之数据类型
  5. Enums and Structs in C#(C#里的枚举和结构) (from codeproject)
  6. iOS内存区域部分内容
  7. Autodesk云计算系列视频 --- 云计算与Civil 3D
  8. MySql笔记:Can't create table 'mydb3.#sql-f48_1' (errno: 150
  9. 学生PHP校园超市网站制作 学生PHP网页毕设源码 学生动态数据库网站作品 PHP电子商务商城购物网站
  10. Windows 10 下基于WSL的开源飞控开发环境配置(Ardupilot/PX4)
  11. 深入理解 gRPC 协议--理解protobuf/.proto/http2
  12. zedgraph画图
  13. 如何将松散的dll打包进需要发布的exe
  14. 树莓派导入h5模型出错OSError: SavedModel file does not exist at: model.h5/{saved_model.pbtxt|saved_model.pb}
  15. Java项目:SSM的校园二手交易平台
  16. 如果我来治理城市大气污染
  17. CT图像重建中的伪影
  18. 【渝粤题库】广东开放大学 企业财务报表分析 形成性考核
  19. Python项目:爬取智联招聘网站的数据分析职位信息并进行可视化分析
  20. 技术牛人博客整理汇总

热门文章

  1. java8中的map与flatmap区别
  2. java muki_再次学习 java 类的编译
  3. MySQL 排名函数.md
  4. Redis Scan 命令
  5. php数组有没有类似next方法,PHP 数组current跟next用法
  6. Java定义变量x初始值为3,JAVA 第一章
  7. tsd3dmapper软件使用方法_TOYO模组选型软件使用方法
  8. irobot擦地机器人故障_33款扫地机器人口碑:售价6350元的戴森口碑垫底,小米、科沃斯谁更好用?...
  9. HTML+CSS+JS实现 ❤️酷炫的时光隧道旅行动特效❤️
  10. typecho模板ajax,typecho ajax登陆