西西软件园多重安全检测下载网站、值得信赖的软件下载站!
软件
软件
文章
搜索

首页编程开发Android → Android开发实现图片异步加载与缓存

Android开发实现图片异步加载与缓存

相关软件相关文章发表评论 来源:西西整理时间:2012/9/16 9:15:54字体大小:A-A+

作者:佚名点击:199次评论:9次标签: Android开发

  • 类型:编程工具大小:13.8M语言:英文 评分:5.5
  • 标签:
立即下载

开发Android程序,一般情况下都会有两个操作,图片的异步加载与缓存,而图片的异步加载大都是从网络读取图片(还有生成本地图片缩略图等操作),为了减少网络操作,加快图片加载速度就需要对图片进行缓存,所以网上的好多图片异步加载方法都是与图片的缓存紧密关联的。但也有可能用户已经有了缓存的相关类库,这样使用起来就会有点麻烦。

  最近一段处理跟图片相关的问题,本来是自己写的图片加载,不过有些状态的控制还是比较烦人的,比如ListView滚动时ImageView的重用,所以本着偷懒与充分利用现有资源的态度去网上搜罗图片异步加载的代码,最终在GreenDroid UI库中找到一个,其中有个AsyncImageView的自定义View用于异步加载图片,不过也像网上的大多数图片异步加载方法一样,是跟图片的缓存关联在一起的,不过只是很简单的内存缓存,无文件缓存。图片的加载方法也如其他的一样是写死了的,这就限制了其使用范围,只可通过InputStream来decode图片,而像生成缩略图或其他一些图片处理的异步处理就无法用途。修改现有类库总比自己从头写来的简单,于是稍微修改了下AsyncImageView,使其可以自定义缓存与图片加载方法,对于AsyncImageView只有一点点的修改,大都是别人源码。

1. 核心类

  ImageLoader:图片加载核心类,内部使用线程池加载图片

  ImageRequest:表示一个图片加载的请求

  AsyncImageView:自定义的图片异步加载View

  LoadMethod:自定义图片加载方法的接口,可以通过实现此接口来自定义图片的加载方法

  CacheCallback:缓存接口,可以通过实现此接口实现对缓存的读写

AsyncImageView.OnImageViewLoadListener:图片加载状态监听(开始,失败,结束)

2。图片加载方法

public void run() {

            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

            final Handler h = mHandler;
            Bitmap bitmap = null;
            Throwable throwable = null;

            h.sendMessage(Message.obtain(h, ON_START));

            try {
                if (TextUtils.isEmpty(mUrl)) {
                    throw new Exception("The given URL cannot be null or empty");
                }

                // 如果自定义了加载方法,则用自定义的方法
                if (mLoadMethod != null) {
                    bitmap = mLoadMethod.load(mUrl);
                } else {

                    InputStream inputStream = null;

                    // Asset
                    if (mUrl.startsWith("file:///android_asset/")) {
                        inputStream = sAssetManager.open(mUrl.replaceFirst(
                                "file:///android_asset/", ""));
                    }
                    // File
                    else if (mUrl.startsWith("file:///") || mUrl.startsWith("/")) {
                        if (mUrl.startsWith("file:///"))
                            mUrl = mUrl.replaceFirst("file:///", "/");
                        inputStream = new FileInputStream(mUrl);
                    }
                    // NetWork
                    else {
                        // 在用URL类加载图片时,发现有的机型上面通过URL类获得的InputStream解析获得的图片总是null,故使用HttpClient
                        HttpGet httpRequest = new HttpGet(mUrl);
                        HttpClient httpclient = new DefaultHttpClient();
                        HttpParams httpParams = new BasicHttpParams();
                        HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
                        HttpConnectionParams.setSoTimeout(httpParams, 5000);
                        httpRequest.setParams(httpParams);
                        HttpResponse response = (HttpResponse)httpclient.execute(httpRequest);
                        HttpEntity entity = response.getEntity();
                        BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
                        InputStream instream = bufHttpEntity.getContent();
                        BufferedInputStream bi = new BufferedInputStream(instream);
                        inputStream = bi;
                    }

                    // 虽然AsyncImageView中有设置BitmapFactory.Options的方法,但一般情况下都未知图片的大小,也就无法计算相应的inSampleSize,
                    // 也就无法设置相应的BitmapFactory.Options,所以一般情况下还是根据自己的需要自定义LoadMethod为好
                    bitmap = BitmapFactory.decodeStream(inputStream, null,
                            (mOptions == null) ? sDefaultOptions : mOptions);
                    inputStream.close();
                }
                if (mBitmapProcessor != null && bitmap != null) {
                    final Bitmap processedBitmap = mBitmapProcessor.processImage(bitmap);
                    if (processedBitmap != null) {
                        bitmap.recycle();
                        bitmap = processedBitmap;
                    }
                }

            } catch (Exception e) {
                Log.e(LOG_TAG, "Error while fetching image", e);
                throwable = e;
            }

            if (bitmap == null) {
                if (throwable == null) {
                    throwable = new Exception("Skia image decoding failed");
                }
                h.sendMessage(Message.obtain(h, ON_FAIL, throwable));
            } else {
                h.sendMessage(Message.obtain(h, ON_END, bitmap));
                if (mCache != null) {
                    mCache.writeCache(TextUtils.isEmpty(mCacheKey) ? mUrl : mCacheKey, bitmap);
                }
            }
        }

  如果自定义了LoadMethod,会调用相应的方法加载图片,如果没有自定义,会使用默认的加载方法,可以加载本地图片,Asset图片与网络图片,GreenDroid的源码中加载网络图片是用的URL的,但我们以前在加载网络图片时遇到一个问题,有的机型通过URL类获得的ImputStream解析图片总是返回null,所以就改为了HttpClient。

3。使用方法

通过AsyncImageView的setPath方法来加载图片,setPath有3个重载方法:

public void setPath(String path)

public void setPath(String path, LoadMethod loadMethod)

public void setPath(String path, LoadMethod loadMethod, String cacheKey)

第一个参数指定要加载的图片的路径,第二个参数为自定义的图片加载方法,若不指定则用默认的。

至于加第三个参数,是做缓存用的,一般要加载的图片的路径都是唯一的,所以一般用第一个参数来做为缓存的Key就行了,但也有特殊情况,比如读取局域网中的图片,一般都是自动获取IP,所以根据图片路径做为缓存的Key可能是不合适的,所以就需要根据需要手动指定用来作为缓存的Key。

/**
     * 设置要加载的图片的路径, 可为网络路径, Asset文件路径(file:///android_asset), 本地图片路径(file:///或/)
     *
     * @param path 要加载的图片的路径, 若为null则加载默认图片
     * @param loadMethod 自定义的图片加载的方法, 可以null, 使用默认的加载方法
     * @param cacheKey 缓存key
     */
    public void setPath(String path, LoadMethod loadMethod, String cacheKey) {

        // Check the url has changed
        if (mBitmap != null && path != null && path.equals(mUrl)) { // TODO mBitmap != null necessary?
            return;
        }

        stopLoading();
        mUrl = path;
        mCacheKey = cacheKey;
        mLoadMethod = loadMethod;

        // Setting the url to an empty string force the displayed image to the
        // default image
        if (TextUtils.isEmpty(mUrl)) {
            mBitmap = null;
            setDefaultImage();
        } else {
            if (!mPaused) {
                reload();
            } else {
                // We're paused: let's look in a synchronous and efficient cache
                // prior using the default image.
                mBitmap = readCache(); // TODO 可能会耗时间
                if (mBitmap != null) {
                    setImageBitmap(mBitmap);
                } else {
                    setDefaultImage();
                }
            }
        }
    }

public void reload(boolean force) {
        if (mRequest == null && mUrl != null) {

            // Prior downloading the image ... let's look in a cache !
            mBitmap = null;
            if (!force) {
                // This may take a long time.
                mBitmap = readCache();
            }

            if (mBitmap != null) {
                setImageBitmap(mBitmap);
                return;
            }

            setDefaultImage();
            mRequest = new ImageRequest(mUrl, this, mImageProcessor, mOptions, mCacheKey);
            mRequest.load(getContext(), mLoadMethod);
            if (ImageLoader.getInstance() != null && ImageLoader.getInstance().getCache() == null) {
                ImageLoader.getInstance().setCache(mCache);
            }
        }

  readCache()用于读取缓存,代码如下:

    private Bitmap readCache() {
        if (mCache != null)
            return mCache.readCache(TextUtils.isEmpty(mCacheKey) ? mUrl : mCacheKey);
        return null;
    }

  其中的mCache由用户能过setCacheCallback(CacheCallback callback)设置用户自定义的缓存方法,由此将图片的加载与缓存分离开,使用户可以使用现有的缓存实现。如要用户指定了缓存Key就使用用户指定的Key,否则就用图片的路径作Key。

4.AsyncImageView中的其他重要方法

reload([boolean force]):重新加载

stopLoading():停止加载,如果当前正在加载则没有效果,如果加载任务在加载线程池队列中则取消。

setDefaultImage...()类方法:设置默认图片。

setPause(boolean pause):是否加载图处

    app制作
    (8)app制作
    一款好的不仅需要有创意的开发人员还要有一款合适的制作软件,有时候一款好用的制作软件可以让开发人员节省很多不必要的时间。另外对于一些不懂编程的人员来说制作一款也不是没有可能的,有些功能强大的制作软件可以让完全不懂编程的人也能制作出一些精美的来,比如一些公司的产品展示这类不需要有自己特色的就可以通过制作软件轻松做出来。这里西西给大家收整理了一些好用的制作软件下载,希望对大家有所帮助。...更多>>
    • appBookv1.0 官方版

      07-04 / 132.6M

      推荐理由:appBook 一次编辑多平台发布 轻松拥有自己的app,appBook是全球首家运行在PC和Mac的移动平台应用编辑制作软
    • 安卓平台反编译神器(Apktool)v6.0.

      02-19 / 13.0M

      推荐理由:Apktool,一款安卓移动平台上的反编译利器!Apktool现已完美兼容Android5.0L,使用它可以修改软件应用名称,
    • myeclipse 10.0

      11-03 / 886M

      推荐理由:MyEclipse 10使用最高级的桌面和Web开发技术,包括 HTML5 和 Java EE 6,支持 JPA 2.0、JSF 2.0 、Eclipsel
    • 移动应用开发工具(AppCan IDE)V3.1

      11-14 / 421.8M

      推荐理由:AppCan应用使用HTML5、CSS3和JavaScript语言编写,通过AppCan IDE提供的本地打包工具或在线编译系统生成可在
    • appMaker中文版v1.0 官方免费版

      03-06 / 315.8M

      推荐理由:appMaker中文版是一款免费的app制作软件,可以制作各种展示类的app。如:移动互动电子书、电子杂志、地产楼
    • 安卓开发(Google Android SDK)r24.

      05-15 / 85.8M

      推荐理由:Google Android SDKAndroid是Google自己研发的手机平台操作系统,该平台基于开源软件Linux,由操作系统、中
    eclipse
    (119)eclipse
    是对的扩展,利用它我们可以在数据库和的开发发布以及应用程序服务器的整合方面极大的提高工作效率。它是功能丰富的集成开发环境,包括了完备的编码调试测试和发布功能,完整支持,,,,,,,。分类在结构上,的特征可以被分为类模型开发工具开发工具应用程序服务器的连接器项目部署服务数据库服务整合帮助...更多>>
    eclipse中文版下载
    (27)eclipse中文版下载
    是一个开放源代码的基于的可扩展开发平台。还包括插件开发环境,,这个组件主要针对希望扩展的软件开发人员,因为它允许他们构建与环境无缝集成的工具。它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,附带了一个标准的插件集,包括开发工具,。汉化方法把语言包中的,文件夹直接覆盖到安装目录中,或者把汉化包放到目录下面。常用快捷键.快速修复.删除当前行.复制当前行到下一行.或者说是空格由于后者与输入法...更多>>
    JAVA软件
    (60)JAVA软件
    软件下载,编程软件下载专题有多款适合编程爱好者学习使用的软件,我们提供了适用于开发者使用的相关软件的各个版本跟新的下载地址,以方便各位爱好者使用学习。如果您有什么好的编程软件可以向我们提供分享下载,如果下载的软件有什么问题也可以向我们提供建议,祝程序员们学习愉快软件开发其实可以不用其他软件的。只需要安装了工具包即可,这个是必须的。并且一定要配置好系统的环境变量。这个可以到网上去查,网上很多。然后进...更多>>

    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶
    • 1 难过难过
    • 5 囧
    • 3 围观围观
    • 2 无聊无聊

    热门评论

    最新评论

    发表评论 查看所有评论(9)

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
    字数: 0/500 (您的评论需要经过审核才能显示)