android 视频的缩略图 缓存机制和 异步加载缩略图
在这次的工作开发项目中,涉及到一个视频缩略图的视频列表;这个在大家看来,制作视频缩略图就是两行代码就搞定的事。确实是这样的,百度一下,每个帖子都知道制作视频缩略图的方法,在这里确实也是一样的,但是我要实现的是让缩略图 在ListView上显示,而且不会出现卡顿,其实也不是特别难,确实很实用;
主要的实现机制就是 异步加载 和 缓存机制 在加上一个绑定TAG机制;接下来就开始去实现吧
先上我的是 结构图:

这个包结构的 自定义 ListView 实现了 仿手机联系人按一定的数据分类 功能,和浮动组标题效果,但是这些功能都不是我今天要强调的,这里只说 怎么样实现缩略图的缓存机制,所以重要的的事 MyVideoThumbLoader类,
简略的的介绍下其他类:
VideoBean 是视频的实体类,用来存储视频数据,包括 视频路径,文件名,时长,。。。做过项目的都懂
VideoUtil 是工具类,写了一些基本的查找视频文件的方法,和创建缩略图的方法
MyPinnedSectionListView 是继承了ListView ,可以不用管内部具体,在这里只用到普通的ListView 就可以了
。。。
在我们拿到了 视频文件信息 ArrayList 并且传到了 MyImageAdapter 内部前提下
,Adapter内部结构如下:
package com.example.jiuan_item3; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map; import android.annotation.SuppressLint;
import android.app.ActionBar.LayoutParams;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.provider.MediaStore;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; /**
* // * listview适配器,设置特殊item(为蓝色背景的首字母栏) //
*/
public class MyImageAdapter extends BaseAdapter {
private Context context;
private ArrayList<VideoBean> datas;
public Map<String, Integer> maps;
private MyVideoThumbLoader mVideoThumbLoader; /**
* @param context
* @param datas
* 具有数据提供的构造
*/
public MyImageAdapter(Context context, ArrayList<VideoBean> datas) {
this.context = context;
this.datas = datas;
sortLetter(datas);
mVideoThumbLoader = new MyVideoThumbLoader();// 初始化缩略图载入方法
} /**
* 获取需要顶部悬浮显示的view,这是另外的功能,可不理会
*/
public View getPinnedSectionView(int position) {
ViewGroup view = (ViewGroup) getView(position, null, null);// x
View vAlpha = view.getChildAt(0);
return vAlpha;
} @Override
public int getCount() {
return datas.size();
} @Override
public VideoBean getItem(int position) {
return datas.get(position);
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) { View view = View.inflate(context, R.layout.alpha_item, null);
final TextView tvAlpha = (TextView) view
.findViewById(R.id.alphaitem_tv_alpha);
TextView tvContent = (TextView) view
.findViewById(R.id.alphaitem_tv_content);
ImageView tvImg = (ImageView) view.findViewById(R.id.imgview); VideoBean myData = getItem(position); tvAlpha.setText(myData.getFileParentVideo());
//实现分组的功能,可不理会
if (maps.get(myData.getFileParentVideo()) == position) {
tvAlpha.setVisibility(View.VISIBLE);
} else {
tvAlpha.setVisibility(View.GONE);
}
tvAlpha.setTag(position);
//重点代码
String path = datas.get(position).getLocationPath();
tvImg.setTag(path);//绑定imageview
mVideoThumbLoader.showThumbByAsynctack(path, tvImg); tvContent.setText(datas.get(position).getVidioName()); return view;
} private void sortLetter(ArrayList<VideoBean> datas) {
// 这是个分组的排序算法,为了让所有的数据统一性
Collections.sort(datas, new Comparator<VideoBean>() {
@Override
public int compare(VideoBean lhs, VideoBean rhs) {
return lhs.getFileParentVideo().compareTo(
rhs.getFileParentVideo());
}
});
maps = new HashMap<String, Integer>();
for (int i = 0; i < datas.size(); i++) {
if (!maps.containsKey(datas.get(i).getFileParentVideo())) {
maps.put(datas.get(i).getFileParentVideo(), i);
}
}
}
}
上面代码中运用到了 MyVideoThumbLoader,这个类,所有贴出这个代码如下:
package com.example.jiuan_item3; import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.provider.MediaStore;
import android.support.v4.util.LruCache;
import android.widget.ImageView; public class MyVideoThumbLoader {
private ImageView imgView;
private String path;
//创建cache
private LruCache<String, Bitmap> lruCache; @SuppressLint("NewApi")
public MyVideoThumbLoader(){
int maxMemory = (int) Runtime.getRuntime().maxMemory();//获取最大的运行内存
int maxSize = maxMemory /4;//拿到缓存的内存大小 lruCache = new LruCache<String, Bitmap>(maxSize){
@Override
protected int sizeOf(String key, Bitmap value) {
//这个方法会在每次存入缓存的时候调用
return value.getByteCount();
}
};
} public void addVideoThumbToCache(String path,Bitmap bitmap){
if(getVideoThumbToCache(path) == null){
//当前地址没有缓存时,就添加
lruCache.put(path, bitmap);
}
}
public Bitmap getVideoThumbToCache(String path){ return lruCache.get(path); }
public void showThumbByAsynctack(String path,ImageView imgview){ if(getVideoThumbToCache(path) == null){
//异步加载
new MyBobAsynctack(imgview, path).execute(path);
}else{
imgview.setImageBitmap(getVideoThumbToCache(path));
} } class MyBobAsynctack extends AsyncTask<String, Void, Bitmap> {
private ImageView imgView;
private String path; public MyBobAsynctack(ImageView imageView,String path) {
this.imgView = imageView;
this.path = path;
} @Override
protected Bitmap doInBackground(String... params) {
//这里的创建缩略图方法是调用VideoUtil类的方法,也是通过 android中提供的 ThumbnailUtils.createVideoThumbnail(vidioPath, kind);
Bitmap bitmap = VideoUtil.createVideoThumbnail(params[0], 70, 50, MediaStore.Video.Thumbnails.MICRO_KIND);
//加入缓存中
if(getVideoThumbToCache(params[0]) == null){
addVideoThumbToCache(path, bitmap);
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if(imgView.getTag().equals(path)){//通过 Tag可以绑定 图片地址和 imageView,这是解决Listview加载图片错位的解决办法之一
imgView.setImageBitmap(bitmap);
}
}
}
}
通过上面的 videoThumbLoader类,就可以看出这个机制的核心所在,异步方法实现图片的加载,这样不会阻塞ui线程,然后缓存加载,又可以节省加载时间;然后在 adapter的geiViewf方法里调用设置缩略图;为了节省每次都去创建缩略图的时间,LruCache实现了图片的缓存机制,LruCache其实底层就是一个 HashMap map 类;具体可以百度下LruCache
public MyVideoThumbLoader(){
int maxMemory = (int) Runtime.getRuntime().maxMemory();//获取最大的运行内存
int maxSize = maxMemory /4;
lruCache = new LruCache<String, Bitmap>(maxSize){
@Override
protected int sizeOf(String key, Bitmap value) {
//这个方法会在每次存入缓存的时候调用,必须要实现的方法
return value.getByteCount();
}
};
}
就这样,全部代码写完了;这个视频缩略图的加载和显示都完美的实现了;
不过以上都是核心代码,如果你看的不是很明白可以留言,
我会上传源码
本版为原创,转载请注明来路;要尊重程序员
android 视频的缩略图 缓存机制和 异步加载缩略图的更多相关文章
- Android学习笔记(二)之异步加载图片
最近在android开发中碰到比较棘手的问题,就是加载图片内存溢出.我开发的是一个新闻应用,应用中用到大量的图片,一个界面中可能会有上百张图片.开发android应用的朋友可能或多或少碰到加载图片内存 ...
- Android中图片的异步加载
转: 1. 为什么要异步加载图片 下载图片比较费时,先显示文字部分,让加载图片的过程在后台,以提升用户体验 2. SoftReference的作用 栈内存—引用 堆内存—对象 Eg: Object ...
- [Android Pro] 使用CursorLoader异步加载数据 from 3.0
Android 3.0引入了CursorLoader实现异步加载数据,为了避免同步查询数据库时阻塞UI线程的问题.在API 11之前可以通过下载支持库,来使之前的系统支持此功能,下载页面为 http: ...
- 多线程异步加载图片async_pictures
异步加载图片 目标:在表格中异步加载网络图片 目的: 模拟 SDWebImage 基本功能实现 理解 SDWebImage 的底层实现机制 SDWebImage 是非常著名的网络图片处理框架,目前国内 ...
- Android-LoaderManager异步加载数据库数据
LoaderManager异步加载数据库数据,是在(Activity/fragment/其他UI等) 加载大量的本地Database库表数据,由于数据大在加载过程中会导致UI线程阻塞,导致用户体验不好 ...
- wemall app商城源码Android之ListView异步加载网络图片(优化缓存机制)
wemall-mobile是基于WeMall的android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享wemall app商城源码Android之L ...
- Android异步加载图像(含线程池,缓存方法)
研究了android从网络上异步加载图像: (1)由于android UI更新支持单一线程原则,所以从网络上取数据并更新到界面上,为了不阻塞主线程首先可能会想到以下方法. 在主线程中new 一个Han ...
- Android批量图片加载经典系列——采用二级缓存、异步加载网络图片
一.问题描述 Android应用中经常涉及从网络中加载大量图片,为提升加载速度和效率,减少网络流量都会采用二级缓存和异步加载机制,所谓二级缓存就是通过先从内存中获取.再从文件中获取,最后才会访问网络. ...
- android ListView异步加载图片(双缓存)
首先声明,参考博客地址:http://www.iteye.com/topic/685986 对于ListView,相信很多人都很熟悉,因为确实太常见了,所以,做的用户体验更好,就成了我们的追求... ...
随机推荐
- 互信息(Mutual Information)
本文根据以下参考资料进行整理: 1.维基百科:https://zh.wikipedia.org/wiki/%E4%BA%92%E4%BF%A1%E6%81%AF 2.新浪博客:http://blog. ...
- 解决真机调试时Eclipse DDMS上打不开/data目录的问题
一般真机调试时DDMS里面的File Explorer是不能打开/data 目录的,不过也很容易解决. 1.首先手机要root.这个很简单,网上一大堆资料和软件. 2.仅仅root之后还不行,下载一个 ...
- C#:注册机的实现【提供源代码下载】
代码下载 C#软件注册机 软件运行结果 参考文章 http://www.cnblogs.com/hanzhaoxin/archive/2013/01/04/2844191.html
- 关于PF_RING/Intel 82599/透明VPN的一些事
接近崩溃的边缘,今天这篇文章构思地点在医院,小小又生病了,宁可吊瓶不吃药,带了笔记本却无法上网,我什么都不能干,想了解一些东西,只能用3G,不敢 开热点,因为没人给我报销流量,本周末我只有一天时间,因 ...
- Apache Solr查询语法(转)
查询参数 常用: q - 查询字符串,必须的. fl - 指定返回那些字段内容,用逗号或空格分隔多个. start - 返回第一条记录在完整找到结果中的偏移位置,0开始,一般分页用. rows - 指 ...
- CMD command
过滤字符串查找:netstat -aon|findstr "80"
- mac电脑如何不生成.DS_STORE文件
执行这个命令,然后重启 defaults write com.apple.desktopservices DSDontWriteNetworkStores true
- [转]Java Spring的Ioc控制反转Java反射原理
转自:http://www.kokojia.com/article/12598.html 学习一个东西的时候,如果想弄明白,最好想想框架内部是如何实现的,如果是我做我会怎么实现.下面我就写一个Ioc ...
- 如何增强 Linux 系统的安全性,第一部分: Linux 安全模块(LSM)简介
http://www.ibm.com/developerworks/cn/linux/l-lsm/part1/ 1.相关背景介绍:为什么和是什么 近年来Linux系统由于其出色的性能和稳定性,开放源代 ...
- Python从内存中使用编译后的模块
在Windows编程的时候,有些时候,我们经常会要使用一些非常规的方法,比如说从内存中加载DLL,然后使用DLL中的函数.于是就思索在用Python的时候是否能够将几个编译好的Pyc合并成一个,然后使 ...