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<Bitmap> 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);




HTC目前的系统结构都是几个储存分区独立存在而又关联的。 一个完整的官方rom解开如下所示(参考) boot.img system.img recovery.img hboot.nb0 data.img cache.img radio.img 等等。。。 我们所说的刷机也仅仅是boot.img引导分区加上system.img系统分区、 那么很多同学卡在第一屏,白屏。或者recovery无法进入(有时候涉及到系统文件不完整,一般都是未刷入第三方recovery) 都是因为boot系统内核(引导分区)加上system不匹配,造成不能正确引导所致。 既然知道了问题所在,接下来就有几种解决方案了 第一:手动刷入boot。或者recovery。 通过fastboot命令刷入。 首先必须要有fastboot支持,官方刷机包里面都自带。我这里提取给大家 解压运行里面的cmd.exe 我的是直接在系统里面提取的cmd。不一定都适用。如果不能运行那就 点击开始-运行-cmd 进入这个文件夹。运行fastboot命令 手机进入fastboot模式有2种方法。如果你的手机能用adb识别到,有时候卡在第一屏也可以识别 你可以先运行 adb devices 如下图显示说明此时adb命令是可以运行的,也可以做更多的事情。 那么我们通过adb命令进入fastboot吧。 运行命令adb reboot bootloader 这样手机就进入fastboot usb模式,如果电脑驱动没装好,这里会识别不到的 第二种进入方法是,手机完全断电,按住音量向下+电源键不放。进入hboot之后点击下电源键 接下来就是刷入boot和recovery了。 把recovery.img和boot.img提取放到刚才下载的文件夹里面。 回到cmd。运行命令。 单刷boot.img命令 : fastboot flash boot boot.img 单刷recovery.img命令 : fastboot flash recovery recovery.img 当然这里不排除有些机器因为民间解锁后刷官方ROM以及升级hboot的问题出错。 我刚才也是刷了4.0系统的官方rom造成错误,然后刷了一个hboot解决掉了 如果以上还达不到你的要求,那么,继续下一步吧。 第二节:刷入原生官方rom 大家经常遇到的就是手机无法进入系统,刷机各种报错,无法进recovery,那好。我刷htc官方rom总行吧。 但是,经过解锁的机器。有很多局限性。什么cid错误啊,什么版本错误啊。。眼花缭乱了吧。 下面我们一htc sensation和htc raider为例说明下刷机方法。 如果htc sensation和raider都是官方解锁的话。刷入完整的官方rom需要先上锁。 具体方法请参考这里: HTC Raider 4G/X710e/突袭者刷回官方ROM教程 http://bbs.dospy.com/viewthread.php?tid=14412965&bbsid=354&page=1&extra=page=1#pid210911214 那如何选择官方ROM呢。哪一个才是适合自己的手机呢? 这里我给大家提供下对应方法, 回到cmd界面,运行命令。 fastboot getvar all
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值