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,相信很多人都很熟悉,因为确实太常见了,所以,做的用户体验更好,就成了我们的追求... ...
随机推荐
- javascript基础08
发现今天居然没有要写,那我就写写之前做的笔记吧. 这是事件的深入: 拖拽逻辑: 第一个: onmousedown : 选择元素 第二个: onmousemove : 移动元素 第三个:onmouseu ...
- hive函数 -- split 字符串分割函数
hive字符串分割函数 split(str, regex) - Splits str around occurances that match regexTime taken: 0.769 secon ...
- InstallShield 2012 Spring优惠升级到最新版本(2015.4.30之前)
InstallShield 2012 Spring即将EOF,所以仍在使用InstallShield 2012 Spring的用户请注意下面内容: InstallShield 2012 Spring升 ...
- mac上安装homebrew
1:关于homebrew下载地址 homebrew下载地址网上版本很多:我用了几个都是显示 404 bad request 如图:均无法现在 有一个网址会给出最新的 安装地址: the URL is: ...
- SQL Developer 4.0 启动报错“unable to create an instance of the java virtual machine located at path”
安装了Oracle之后,第一件事情就是想想怎么去连接,进而操作.SQL Developer是官方提供的强大工具,个人看来也是第一选择. 目前官网提供的最新版是4.0.1.14.48,下载下来之后,就跃 ...
- spring-boot 加载本地静态资源文件路径配置
1.spring boot默认加载文件的路径是 /META-INF/resources/ /resources/ /static/ /public/ 这些目录下面, 当然我们也可以从spring bo ...
- Windows 系统下设置Nodejs NPM全局路径
Windows下的Nodejs npm路径是appdata,很不爽,想改回来,但是在cmd下执行以下命令也无效 npm config set cache "D:\nodejs\node_ca ...
- 通过Web.config实现301重定向
通过Web.config实现301重定向 IIS7以上可以通过修改Web.config实现IIS设置 现在我们通过Web.config实现301重定向 <system.webServer> ...
- Excel 二级下拉菜单
http://jingyan.baidu.com/article/cd4c2979f31967756f6e6066.html http://hi.baidu.com/chenshake/item/e1 ...
- 解决Maven关于本地jar包的打包处理
在使用maven进行jar包管理时,通过我们都是通过maven去下载一些jar包,但有些jar在maven上没有,所以就就可能在本地直接手动加入一些需要用到的外部jar包.但如果我们用maven pa ...