在这次的工作开发项目中,涉及到一个视频缩略图的视频列表;这个在大家看来,制作视频缩略图就是两行代码就搞定的事。确实是这样的,百度一下,每个帖子都知道制作视频缩略图的方法,在这里确实也是一样的,但是我要实现的是让缩略图 在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 视频的缩略图 缓存机制和 异步加载缩略图的更多相关文章

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

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

  2. Android中图片的异步加载

    转: 1.  为什么要异步加载图片 下载图片比较费时,先显示文字部分,让加载图片的过程在后台,以提升用户体验 2.  SoftReference的作用 栈内存—引用 堆内存—对象 Eg: Object ...

  3. [Android Pro] 使用CursorLoader异步加载数据 from 3.0

    Android 3.0引入了CursorLoader实现异步加载数据,为了避免同步查询数据库时阻塞UI线程的问题.在API 11之前可以通过下载支持库,来使之前的系统支持此功能,下载页面为 http: ...

  4. 多线程异步加载图片async_pictures

    异步加载图片 目标:在表格中异步加载网络图片 目的: 模拟 SDWebImage 基本功能实现 理解 SDWebImage 的底层实现机制 SDWebImage 是非常著名的网络图片处理框架,目前国内 ...

  5. Android-LoaderManager异步加载数据库数据

    LoaderManager异步加载数据库数据,是在(Activity/fragment/其他UI等) 加载大量的本地Database库表数据,由于数据大在加载过程中会导致UI线程阻塞,导致用户体验不好 ...

  6. wemall app商城源码Android之ListView异步加载网络图片(优化缓存机制)

    wemall-mobile是基于WeMall的android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享wemall app商城源码Android之L ...

  7. Android异步加载图像(含线程池,缓存方法)

    研究了android从网络上异步加载图像: (1)由于android UI更新支持单一线程原则,所以从网络上取数据并更新到界面上,为了不阻塞主线程首先可能会想到以下方法. 在主线程中new 一个Han ...

  8. Android批量图片加载经典系列——采用二级缓存、异步加载网络图片

    一.问题描述 Android应用中经常涉及从网络中加载大量图片,为提升加载速度和效率,减少网络流量都会采用二级缓存和异步加载机制,所谓二级缓存就是通过先从内存中获取.再从文件中获取,最后才会访问网络. ...

  9. android ListView异步加载图片(双缓存)

    首先声明,参考博客地址:http://www.iteye.com/topic/685986 对于ListView,相信很多人都很熟悉,因为确实太常见了,所以,做的用户体验更好,就成了我们的追求... ...

随机推荐

  1. How to get blob data using javascript XmlHttpRequest by sync

    Tested: Firefox 33+ OK Chrome 38+ OK IE 6 -- IE 10 Failed Thanks to 阮一峰's blog: http://www.ruanyifen ...

  2. SVN仓库删除最近的提交,还原到某日期以前的版本(svn仓库 删除最近几次更改)

    由于某日删除了SVN仓库的大量内容,现在突然想恢复,又要保留LOG的连贯性(恢复出来的已删除文件,会是新增,没有之前的历史Log了),所以才有了这需求. Dump版本库的版本(457以后版本不要) - ...

  3. 使用 Aircrack-ng 破解 WEP 和 WPA/WPA2 加密的 Wi-Fi 密码。(转)

    1.首先请不要使用此方法去搞破坏,去蹭Wi-Fi,因为不装逼地说,我认为技术本身的价值很大,尤其是在学习这个技术的过程中解决遇到的问题,当经过重重困难最后终于成功之后的喜悦又怎么能拿去蹭网呢.我在此过 ...

  4. django文件上传下载

    views: def mgmt_files(request): #列出树形目录,上传文件页面 if request.method == 'POST': path_root = "D:\\py ...

  5. 构造函数模式自己定义js对象

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. exam help

    http://forceprepare.com/ http://forcecertified.com/certifications/certified-developer/ http://blog.l ...

  7. IOC性能对比

  8. Android系列--DOM、SAX、Pull解析XML

    您可以通过点击 右下角 的按钮 来对文章内容作出评价, 也可以通过左下方的 关注按钮 来关注我的博客的最新动态. 如果文章内容对您有帮助, 不要忘记点击右下角的 推荐按钮 来支持一下哦 如果您对文章内 ...

  9. PHP查看SSL证书信息

    <? $str = file_get_contents('2.cer'); print_r(openssl_x509_parse($str)); ?> 证书需要使用base64编码的方式c ...

  10. python 与数据结构

    在上面的文章中,我写了python中的一些特性,主要是简单为主,主要是因为一些其他复杂的东西可以通过简单的知识演变而来,比如装饰器还可以带参数,可以使用装饰类,在类中不同的方法中调用,不想写的太复杂, ...