android 显示流程,android 图片解码显示流程

问题来源

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 的显示处理,所以可以显示动画。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值