问题来源

android 可以在 gallery 里面显示内部存储的图片,支持 jpeg,png,gif,bmp 等,甚至文件类型和图片后缀名不一致,只要是图片文件就能显示,然后 git 只会显示第一帧图像,然而 android 其实是可以显示 gif 动画的,在浏览器里打开 gif 动画,就能够正常加载显示。

Gallery 查看图片

gallery 实现了Gallery/src/com/android/camera/ViewImage.java
                        ImageViewTouchBase newView =                                mSlideShowImageViews[mSlideShowImageCurrent];                        newView.setVisibility(View.VISIBLE);                        newView.setImageRotateBitmapResetBase(bitmap, true);                        newView.bringToFront();

通过自己实现的 ImageViewTouchBase 装载图片并显示
ImageViewTouchBase 继承自 framework 的 ImageView
package com.android.camera;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Matrix;import android.graphics.RectF;import android.graphics.drawable.Drawable;import android.os.Handler;import android.util.AttributeSet;import android.view.KeyEvent;import android.widget.ImageView;abstract class ImageViewTouchBase extends ImageView {

framework 处理图片

ImageView 是 android 图片框架实现通用图片处理显示类: 可以显示 resource 里面的图片,
    public void setImageResource(int resId) {        if (mUri != null || mResource != resId) {            updateDrawable(null);            mResource = resId;            mUri = null;            final int oldWidth = mDrawableWidth;            final int oldHeight = mDrawableHeight;            resolveUri();            if (oldWidth != mDrawableWidth || oldHeight != mDrawableHeight) {                requestLayout();            }            invalidate();        }    }

我们在 gallery 里面打开的图片调用是通过 uri 传过来的,
    public void setImageURI(Uri uri) {        if (mResource != 0 ||                (mUri != uri &&                 (uri == null || mUri == null || !uri.equals(mUri)))) {            updateDrawable(null);            mResource = 0;            mUri = uri;            final int oldWidth = mDrawableWidth;            final int oldHeight = mDrawableHeight;            resolveUri();            if (oldWidth != mDrawableWidth || oldHeight != mDrawableHeight) {                requestLayout();            }            invalidate();        }    }

android 会解析 uri 得到目标文件路径
        } else if (mUri != null) {            String scheme = mUri.getScheme();            if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) {                try {                    // Load drawable through Resources, to get the source density information                    ContentResolver.OpenResourceIdResult r =                            mContext.getContentResolver().getResourceId(mUri);                    d = r.r.getDrawable(r.id);                } catch (Exception e) {                    Log.w("ImageView", "Unable to open content: " + mUri, e);                }            } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)                    || ContentResolver.SCHEME_FILE.equals(scheme)) {                InputStream stream = null;                try {                    stream = mContext.getContentResolver().openInputStream(mUri);                    d = Drawable.createFromStream(stream, null);                } catch (Exception e) {                    Log.w("ImageView", "Unable to open content: " + mUri, e);                } finally {                    if (stream != null) {                        try {                            stream.close();                        } catch (IOException e) {                            Log.w("ImageView", "Unable to close content: " + mUri, e);                        }                    }                }        } else {                d = Drawable.createFromPath(mUri.toString());            }

我们点击 gallery 的图片会产生包含 content 的 uri: I/ActivityManager( 1304): START u0 {dat= content://media/external/images/media/21 cmp=com.android.gallery/com.android.camera.ViewImage (has extras)} from pid 1706

然后通过 Drawable 从 inputstream 里面解析创建 Drawable 对象
    public static Drawable createFromStream(InputStream is, String srcName) {        Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, srcName != null ? srcName : "Unknown drawable");        try {            return createFromResourceStream(null, null, is, srcName, null);        } finally {            Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);        }    }

后面的流程就是交给 skia 解析然后获得一个 bitmap 并返回了。 skia 的 decode 可以自动识别 steam 里面的数据流创建相应的 decoder。

问题答案

framework 是通用的图片显示处理,最后只返回了一个 bitmap ,所以 gif 只能处理第一帧图像了,但是 browser 是从新实现了图像显示接口,有专门针对 gif 的显示处理,所以可以显示动画。


作者:jingxia2008 发表于2014-6-19 15:04:25 原文链接 阅读:0 评论:0 查看评论

更多相关文章

  1. android uiautomator 截取图片
  2. Android中TextView属性
  3. Android中的Selector 背景选择器
  4. 浅谈android的selector背景选择器
  5. android的selector背景选择器
  6. Android(安卓)textview 只显示一行,多余部分显示.....
  7. 关于android中的gif实现
  8. Android中图片Bitmap的缩放
  9. 浅谈android的selector背景选择器

随机推荐

  1. findViewById()使用常见错误
  2. Android应用程序启动过程源代码分析
  3. UI控件之显示文本控件TextView(上)
  4. Android(安卓)设置默认桌面,默认应用,辅
  5. Android(安卓)Matrix
  6. Android(安卓)动态加载APK--代码安装、获
  7. TextView属性大全
  8. Android三大动画详解
  9. android中handler总结
  10. Android软件开发需要学什么