一、简介

二、代码流程

1.private Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();来起到缓存图片的作用

2.每当要访问图片,先在map找,找不到则new Thread().start(),访问网络得到图片,再传给handler,

Message message = handler.obtainMessage(0, drawable);
handler.sendMessage(message);

3.handler若收到message 就产生回调,没轩imageView的图片信息callback.imageLoaded((Drawable) msg.obj);

三、代码
1.xml
(1)activity_main.xml

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<ImageView
android:id="@+id/imageView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon"
/>
<ImageView
android:id="@+id/imageView02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon"
/>
<ImageView
android:id="@+id/imageView03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon"
/>
</LinearLayout>

(2)AndroidManifest.xml

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

2.java
(1)MainActivity.java

 import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.ImageView; public class MainActivity extends Activity {
/** Called when the activity is first created. */
private AsyncImageLoader loader = new AsyncImageLoader();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
loadImage("http://www.android.com/images/icon-partners.png", R.id.imageView01);
loadImage("http://www.android.com/images/icon-dev.png", R.id.imageView02);
loadImage("http://www.android.com/images/icon-market.png", R.id.imageView03);
}
//url:下载图片的URL
//id:ImageView控件的ID
private void loadImage(final String url, final int id) {
// 如果缓存过就会从缓存中取出图像,ImageCallback接口中方法也不会被执行
ImageView imageView = (ImageView)findViewById(id);
//把imageVieww传给CallbackImpl,回调时就可以设置图片
CallbackImpl callbackImpl = new CallbackImpl(imageView);
Drawable cacheImage =
loader.loadDrawable(url, callbackImpl);
if (cacheImage != null) {
imageView.setImageDrawable(cacheImage);
}
}
}

(2)AsyncImageLoader.java

 import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Map; import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message; //该类的主要作用是实现图片的异步加载
public class AsyncImageLoader {
//图片缓存对象
//键是图片的URL,值是一个SoftReference对象,该对象指向一个Drawable对象
//这样并不影响image被garbage collecter回收
private Map<String, SoftReference<Drawable>> imageCache =
new HashMap<String, SoftReference<Drawable>>(); //实现图片的异步加载
public Drawable loadDrawable(final String imageUrl,final ImageCallback callback){
//查询缓存,查看当前需要下载的图片是否已经存在于缓存当中
if(imageCache.containsKey(imageUrl)){
SoftReference<Drawable> softReference=imageCache.get(imageUrl);
if(softReference.get() != null){//如果为null,则说明被垃圾回收器回收了
return softReference.get();
}
} //Handler和UI是同一线程的
final Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
//msg.obj是handler.obtainMessage(0, drawable);传过来的
callback.imageLoaded((Drawable) msg.obj);
}
}; //如果缓存没有,则新开辟一个线程,该线程用于进行图片的下载
//每下载一个图片,都 会开辟一个新线程,和UI不是同一线程的
new Thread(){
public void run() {
Drawable drawable=loadImageFromUrl(imageUrl);
//把图片加到map中,以缓存图片,则下次访问不用访问网络
imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
Message message = handler.obtainMessage(0, drawable);
handler.sendMessage(message);
};
}.start();
return null;//这里不能return drawable,因为它是在另一个线程,此时drawable可能还没值
}
//该方法用于根据图片的URL,从网络上下载图片
protected Drawable loadImageFromUrl(String imageUrl) {
try {
//根据图片的URL,下载图片,并生成一个Drawable对象
return Drawable.createFromStream(new URL(imageUrl).openStream(), "src");
} catch (Exception e) {
throw new RuntimeException(e);
}
} //回调接口
public interface ImageCallback{
public void imageLoaded(Drawable imageDrawable);
}
}

(3)CallbackImpl.java

 import android.graphics.drawable.Drawable;
import android.widget.ImageView; public class CallbackImpl implements AsyncImageLoader.ImageCallback{
private ImageView imageView ; public CallbackImpl(ImageView imageView) {
super();
this.imageView = imageView;
} @Override
public void imageLoaded(Drawable imageDrawable) {
imageView.setImageDrawable(imageDrawable);
} }

ANDROID_MARS学习笔记_S04_009_用java.lang.ref.SoftReference作缓存,android.os.Handler和new Thread异步加载略图片的更多相关文章

  1. Java学习笔记之——this关键字、非静态成员属性和静态成员属性的区别、类的加载顺序

    一.this关键字 1.代表当前类的对象 2.通过” . ”调用成员属性和成员方法 3.通过this可以区分成员属性和参数 参数名和属性名相同的情况,默认是参数名 二.非静态成员属性和静态成员属性的区 ...

  2. 深入探讨 java.lang.ref 包--转

    概述 Java.lang.ref 是 Java 类库中比较特殊的一个包,它提供了与 Java 垃圾回收器密切相关的引用类.这些引用类对象可以指向其它对象,但它们不同于一般的引用,因为它们的存在并不防碍 ...

  3. Android学习笔记(二)之异步加载图片

    最近在android开发中碰到比较棘手的问题,就是加载图片内存溢出.我开发的是一个新闻应用,应用中用到大量的图片,一个界面中可能会有上百张图片.开发android应用的朋友可能或多或少碰到加载图片内存 ...

  4. wemall app商城源码中基于JAVA的Android异步加载图片管理器代码

    wemall doraemon是Android客户端程序,服务端采用wemall微信商城,不对原商城做任何修改,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可随意定制修改.本文分享其中 ...

  5. 学习笔记(三)--->《Java 8编程官方参考教程(第9版).pdf》:第十章到十二章学习笔记

    回到顶部 注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法 ...

  6. 深入探讨 java.lang.ref 包

    深入探讨 java.lang.ref 包 本文主要探讨了 java.lang.ref 包的使用方法,以及源码解读.并就该包在不同 JVM 上的表现进行了比较与分析.通过阅读本文,读者可以加深对 jav ...

  7. Android学习问题记录之java.lang.UnsatisfiedLinkError

    1.问题描述 Android Studio引入第三方类库时,出现错误java.lang.UnsatisfiedLinkError: 11-09 14:58:05.500 13280-13280/cn. ...

  8. ANDROID_MARS学习笔记_S01原始版_023_MP3PLAYER005_用广播BroacastReciever实现后台播放不更新歌词

    一.代码流程1.自定义一个AppConstant.LRC_MESSAGE_ACTION字符串表示广播"更新歌词" 2.在PlayerActivity的onResume()注册Bro ...

  9. ANDROID_MARS学习笔记_S01原始版_023_MP3PLAYER004_同步显示歌词

    一.流程分析 1.点击播放按钮,会根据lrc名调用LrcProcessor的process()分析歌词文件,得到时间队列和歌词队列 2.new一个hander,把时间队列和歌词队列传给自定义的线程类U ...

随机推荐

  1. Python入门学习教程:数据库操作,连接MySql数据库

    各位志同道合的同仁可以点击上方关注↑↑↑↑↑↑ 本教程致力于程序员快速掌握Python语言编程. 本文章内容是基于上次课程Python教程:Python教程:连接数据库,对数据进行增删改查操作 和py ...

  2. MySQL5.7.12新密码登录方式及密码策略

    在Centos6.6上安装MySQL5.7.12时,遇到了一个问题 安装后在/root目录下没有发现有.mysql_secret这个文件,所以没有没法按照官方文档上说的那样使用,这里记录下, 解决方式 ...

  3. Flie类

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...

  4. static的用途

    1)限制变量的作用域:即在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变: 2)限制变量的存储域:<a>在模块内(但在函数体外),一个被声明为静态的变量,可以被模块内的所 ...

  5. [转]CSS 模块

    CSS 模块 如果你想知道 CSS 最近发展的转折点,你应该选择去观看 Christopher Chedeau 在2014年11月的 NationJS 大会上做的名称为 CSS in JS 的分享.不 ...

  6. 实例:图像载入、显示、混合与输出[OpenCV 笔记8]

    是的是的,忍着尿意努力更新,就是为了更到wuli男神的部分,当然要把男神放在前面镇楼,欢迎下载配图,具体操作见code wuliEddie.jpg logo.png results.jpg LoadS ...

  7. ubuntu 安装qt 5.1的各种错误

    错误太多了,我就不一一说 了,直接一条命令搞定 sudo apt-:i386 libx11-:i386 libglib2.-:i386 libfreetype6:i386 libSM6:i386 li ...

  8. 九度OJ 1118 数制转换

    题目地址:http://ac.jobdu.com/problem.php?pid=1118 题目描述: 求任意两个不同进制非负整数的转换(2进制-16进制),所给整数在long所能表达的范围之内.   ...

  9. 《APUE》第三章笔记(2)

    read函数 调用read函数从打开的文件中读数据. #include <unistd.h> ssize_t read(int filedes, void *buf, size_t nby ...

  10. linux文件属性权限相关

    一个linux目录或者文件,都会有一个所属主和所属组. 所属主,即文件的拥有者,而所属组,即该文件所属主所在的一个组. linux文件属性 包括文件类型 - d  l  b c s 依次表示 普通文件 ...