ANDROID_MARS学习笔记_S04_009_用java.lang.ref.SoftReference作缓存,android.os.Handler和new Thread异步加载略图片
一、简介


二、代码流程
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异步加载略图片的更多相关文章
- Java学习笔记之——this关键字、非静态成员属性和静态成员属性的区别、类的加载顺序
一.this关键字 1.代表当前类的对象 2.通过” . ”调用成员属性和成员方法 3.通过this可以区分成员属性和参数 参数名和属性名相同的情况,默认是参数名 二.非静态成员属性和静态成员属性的区 ...
- 深入探讨 java.lang.ref 包--转
概述 Java.lang.ref 是 Java 类库中比较特殊的一个包,它提供了与 Java 垃圾回收器密切相关的引用类.这些引用类对象可以指向其它对象,但它们不同于一般的引用,因为它们的存在并不防碍 ...
- Android学习笔记(二)之异步加载图片
最近在android开发中碰到比较棘手的问题,就是加载图片内存溢出.我开发的是一个新闻应用,应用中用到大量的图片,一个界面中可能会有上百张图片.开发android应用的朋友可能或多或少碰到加载图片内存 ...
- wemall app商城源码中基于JAVA的Android异步加载图片管理器代码
wemall doraemon是Android客户端程序,服务端采用wemall微信商城,不对原商城做任何修改,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可随意定制修改.本文分享其中 ...
- 学习笔记(三)--->《Java 8编程官方参考教程(第9版).pdf》:第十章到十二章学习笔记
回到顶部 注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法 ...
- 深入探讨 java.lang.ref 包
深入探讨 java.lang.ref 包 本文主要探讨了 java.lang.ref 包的使用方法,以及源码解读.并就该包在不同 JVM 上的表现进行了比较与分析.通过阅读本文,读者可以加深对 jav ...
- Android学习问题记录之java.lang.UnsatisfiedLinkError
1.问题描述 Android Studio引入第三方类库时,出现错误java.lang.UnsatisfiedLinkError: 11-09 14:58:05.500 13280-13280/cn. ...
- ANDROID_MARS学习笔记_S01原始版_023_MP3PLAYER005_用广播BroacastReciever实现后台播放不更新歌词
一.代码流程1.自定义一个AppConstant.LRC_MESSAGE_ACTION字符串表示广播"更新歌词" 2.在PlayerActivity的onResume()注册Bro ...
- ANDROID_MARS学习笔记_S01原始版_023_MP3PLAYER004_同步显示歌词
一.流程分析 1.点击播放按钮,会根据lrc名调用LrcProcessor的process()分析歌词文件,得到时间队列和歌词队列 2.new一个hander,把时间队列和歌词队列传给自定义的线程类U ...
随机推荐
- 11.14 noip模拟试题
题目名称 正确答案 序列问题 长途旅行 英文名称 answer sequence travel 输入文件名 answer.in sequence.in travel.in 输出文件名 answer ...
- php 中json_decode()和json_encode()的使用方法
1.json_decode() json_decode (PHP 5 >= 5.2.0, PECL json >= 1.2.0) json_decode — 对 JSON 格式的字符串进行 ...
- Help View修复
好吧,手贱把ProgramData里关于Help View的某些数据删除了 (在任何情况下都不要删除此文件夹中的任何数据).即使卸载后重新安装也出现错误,可以参考的http://social.msdn ...
- Visual C++ 打印编程技术-打印基础知识
打印机介绍 1.打印术语 *: 1 英寸= 2.54 厘米(cm)= 25.4 毫米(mm) cpi (Characters Per Inch): 每英寸内所含的字符数,用来表示字符的大小.间距 cp ...
- mysql更改root密码及root远程登录
1.更改root密码 use mysql; update user set password=password('petecc') where user='root'; 2.root远程登录 1 up ...
- jfinal不能正确加载html网页,总是报错的解决方法
今天自学jfinal,遇到一个很奇怪的问题,render("/index.html");总是报错. 仔细看错误日志,才发现原来是因为html网页放到了WEB-INF文件夹下面了,所 ...
- Codevs 1648 最大和
1648 最大和 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description N个数围成一圈,要求从中选择若干个连续的数(注意每个 ...
- 九度OJ 1081 递推数列 -- 矩阵二分乘法
题目地址:http://ac.jobdu.com/problem.php?pid=1081 题目描述: 给定a0,a1,以及an=p*a(n-1) + q*a(n-2)中的p,q.这里n >= ...
- siege 压力测试
Ben: $ siege -u shemp.whoohoo.com/Admin.jsp -d1 -r10 -c25 ..Siege 2.65 2006/05/11 23:42:16 ..Prepari ...
- gentoo下的wpa_supplicant无线网配置
在linux使用wpa_supplicant获得无线网的最痛苦的是莫过于去配置wpa_supplicant.conf文件了(当然对于linux老手这不算什么), 但是可以用一种简便的方法直接输入命令行 ...