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 ...
随机推荐
- Atom编辑器入门到精通(四) Atom使用进阶
在本节中将介绍Atom提供的更高级的使用技巧,通过这些技巧将会进一步提高你的代码编写效率 代码片段(Snippets) Snippets是一种在代码中快捷插入代码块的方式,下面是维基百科中对Snipp ...
- asp.net 开发问题:Web 服务器上的请求筛选被配置为拒绝该请求,因为内容长度超过配置的值。
"Web 服务器上的请求筛选被配置为拒绝该请求,因为内容长度超过配置的值." 这个问题在开发需要上传文件的时候可能会遇到,今天遇到这个问题,百度过也有挺多的修改方法. 方法1: 修 ...
- 关于dialog的一点知识
一般我们比较常用的就是AlertDialog,这个一般也不直接构造,而是用系统提供的builder构造器去构造一个dialog. AlertDialog.Builder builder = new A ...
- Android中log4j的运用
网上一查关于android上面运用Log4j的运用,各种说需要添加多样的包的,照着log4j的官网教程看了下,给了个简单的输出到console上面的代码,似乎没什么用.看网上关于Log4j更多是在ja ...
- MVC小系列(十二)【RenderAction和RenderPartial区别】
二者作用:RenderAction:渲染分部视图到页面上,要求提供Action和控制器名称RenderPartial:渲染分部视图到页面上,要求提供分部视图的名称,即路径,如果是在当前控制下或者sha ...
- MVC小系列(四)【向RouteData里扔数据】
向RouteData里扔数据 当Url做路由之后,QueryString里当然是不可能再存你的信息了,而信息包括控制器,action,参数都会存储在RouteData里,而一般这里的信息都是通过前一个 ...
- java新手笔记9 类的封装示例
1.bank类 package com.yfs.javase; //类封装 public class BankCard { //属性 int balance;//默认0 实例变量 分配给每个对象一个 ...
- java.lang.Exception: Socket bind failed 服务器端口冲突-->修改端口
需要修改三个端口号:%apache_tomcat6%/conf/server.xml 四月 11, 2014 11:39:25 上午 org.apache.catalina.core.AprLifec ...
- jQuery的基础语法实例
jQuery 基础语法 jQuery 语法是为 HTML 元素的选取编制的,可以对元素执行某些操作. 基础语法是:$(selector).action() 美元符号定义 jQuery 选择符(sele ...
- 记录一次mount问题
linux centos 6.5 _64 oracle 11.2g 今天接到一个客户电话说重启了服务器,数据库没有重启来,看了数据库的报错 没有找到control文件的路径,数据库启动到了 unmo ...