Android(安卓)4.0 gallery2 生成video thumbnail的过程
通过print callstack得知gallery里面获得thumbnail 是通过LocalVideo.requestImage往下调用的:
com.android.gallery3d.data.LocalVideo.requestImage(LocalVideo.java:143)
com.android.gallery3d.ui.AlbumSlidingWindow$AlbumDisplayItem.startLoadBitmap(AlbumSlidingWindow.java:372)
com.android.gallery3d.ui.AbstractDisplayItem.requestImage(AbstractDisplayItem.java:81)
在LocalVideo.java里面直接调用return LocalVideoRequest对象:
所以简单的说thumbnail就是LocalVideoRequest得到的,细节就要往下看了。
@Override public Job requestImage(int type) { return new LocalVideoRequest(mApplication, getPath(), type, filePath);}
-
LocalVideoRequest直接调用ImageCacheRequest的实现
-
LocalVideoRequest里面override了onDecodeOriginal方法
public static class LocalVideoRequest extends ImageCacheRequest { private String mLocalFilePath; LocalVideoRequest(GalleryApp application, Path path, int type, String localFilePath) { super(application, path, type, LocalImage.getTargetSize(type)); mLocalFilePath = localFilePath; } @Override public Bitmap onDecodeOriginal(JobContext jc, int type) { Bitmap bitmap = BitmapUtils.createVideoThumbnail(mLocalFilePath); if (bitmap == null || jc.isCancelled()) return null; return bitmap; } }
ImageCacheRequest:
1. 首先创建ImageCacheService对象[在ImageCacheRequest::run()]
ImageCacheService cacheService = mApplication.getImageCacheService();
2. 通过CacheService.getImageData获取ImageData
ImageData data = cacheService.getImageData(mPath, mType);
3. 如果data不为null,对data进行decode,然后return,
如果data为空就调用上面说到的onDecodeOriginal创建新的thumbnail
再把经过处理的bitmap写进文件里面(cacheService.putImageData)
if (data != null) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.ARGB_8888; Bitmap bitmap = DecodeUtils.requestDecode(jc, data.mData, data.mOffset, data.mData.length - data.mOffset, options); if (bitmap == null && !jc.isCancelled()) { Log.w(TAG, "decode cached failed " + debugTag); } return bitmap;} else { Bitmap bitmap = onDecodeOriginal(jc, mType); if (jc.isCancelled()) return null; if (bitmap == null) { Log.w(TAG, "decode orig failed " + debugTag); return null; } if (mType == MediaItem.TYPE_MICROTHUMBNAIL) { bitmap = BitmapUtils.resizeDownAndCropCenter(bitmap, mTargetSize, true); } else { bitmap = BitmapUtils.resizeDownBySideLength(bitmap, mTargetSize, true); } if (jc.isCancelled()) return null; byte[] array = BitmapUtils.compressBitmap(bitmap); if (jc.isCancelled()) return null; cacheService.putImageData(mPath, mType, array); return bitmap;}
ImageCacheService的实现:
有一个private对象: private BlobCache mCache;
通过在BlobCache.java增加log,BlobCache的路径为:
/mnt/sdcard/Android/data/com.android.gallery3d/cache/imgcache
// Creates the cache. Three files will be created:// path + ".idx", path + ".0", and path + ".1"// The ".0" file and the ".1" file each stores data for a region. Each of// them can grow to the size specified by maxBytes. The maxEntries parameter// specifies the maximum number of entries each region can have. If the// "reset" parameter is true, the cache will be cleared before use.public BlobCache(String path, int maxEntries, int maxBytes, boolean reset) throws IOException { this(path, maxEntries, maxBytes, reset, 0);}public BlobCache(String path, int maxEntries, int maxBytes, boolean reset, int version) throws IOException { mIndexFile = new RandomAccessFile(path + ".idx", "rw"); mDataFile0 = new RandomAccessFile(path + ".0", "rw"); mDataFile1 = new RandomAccessFile(path + ".1", "rw"); mVersion = version;
Gallery的cache目录:
/mnt/sdcard/Android/data/com.android.gallery3d/cache/
imgcache.0
imgcache.1
imgcache.idx
BlobCache的描述(BlobCache.java):
// This is an on-disk cache which maps a 64-bits key to a byte array.//// It consists of three files: one index file and two data files. One of the// data files is "active", and the other is "inactive". New entries are// appended into the active region until it reaches the size limit. At that// point the active file and the inactive file are swapped, and the new active// file is truncated to empty (and the index for that file is also cleared).// The index is a hash table with linear probing. When the load factor reaches// 0.5, it does the same thing like when the size limit is reached.//// The index file format: (all numbers are stored in little-endian)// [0] Magic number: 0xB3273030// [4] MaxEntries: Max number of hash entries per region.// [8] MaxBytes: Max number of data bytes per region (including header).// [12] ActiveRegion: The active growing region: 0 or 1.// [16] ActiveEntries: The number of hash entries used in the active region.// [20] ActiveBytes: The number of data bytes used in the active region.// [24] Version number.// [28] Checksum of [0..28).// [32] Hash entries for region 0. The size is X = (12 * MaxEntries bytes).// [32 + X] Hash entries for region 1. The size is also X.//// Each hash entry is 12 bytes: 8 bytes key and 4 bytes offset into the data// file. The offset is 0 when the slot is free. Note that 0 is a valid value// for key. The keys are used directly as index into a hash table, so they// should be suitably distributed.//// Each data file stores data for one region. The data file is concatenated// blobs followed by the magic number 0xBD248510.//// The blob format:// [0] Key of this blob// [8] Checksum of this blob// [12] Offset of this blob// [16] Length of this blob (not including header)// [20] Blob//// Below are the interface for BlobCache. The instance of this class does not// support concurrent use by multiple threads.//// public BlobCache(String path, int maxEntries, int maxBytes, boolean reset) throws IOException;// public void insert(long key, byte[] data) throws IOException;// public byte[] lookup(long key) throws IOException;// public void lookup(LookupRequest req) throws IOException;// public void close();// public void syncIndex();// public void syncAll();// public static void deleteFiles(String path);
更多相关文章
- 类和 Json对象
- Android网文
- Android应用程序绑定服务(bindService)的过程源代码分析(3)
- Android(安卓)Adapter详解
- Android调用系统相机拍照并保存到指定位置
- Android(安卓)MediaPlayer 字幕同步
- Android(安卓)调用系统相机拍照保存以及调用系统相册的方法
- Android如何获取网络连接状态及怎样调用网络配置界面
- Android之DatePickerDialog用法(日历的用法)