欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > 内容正文

WP7应用开发笔记 继承BitmapSource并使用独立存储来缓存远程的图片

来源: 开发者 投稿于  被查看 7559 次 评论:46

WP7应用开发笔记 继承BitmapSource并使用独立存储来缓存远程的图片


作为Web App访问远程图片是经常的遇到功能,Wp本身提供了Image 很好的支持通过图片的Uri显示图片
public ImageSource Source { get; set; }

<Image Source="http://www.2cto.com/uploadfile/2012/0301/20120301094720431.png" />
为了减少网络流量,需要将图片缓存到本地数据存储中。复习一下WP的本地数据存储:
 
Windows Phone 本地数据存储
Windows Phone 应用程序可以使用独立存储将数据储存到手机本地。应用程序可以通过三种方式储存数据:
1. 设置:使用 IsolatedStorageSettings 类将数据存储为键/值对。
2. 文件和文件夹:使用 IsolatedStorageFile 类存储文件和文件夹。
3. 本地数据库:7.1新增,只能支持LINQ TO SQL ,不能写SQL语句。
 
本地存储图片
首先图片应该选择IsolatedStorageFile来存储:
WP提供了一个叫IsolatedStorageFileStream的Stream和FileStream操作一样
using (var fileStream = isolatedStorageFile.OpenFile(filePath, FileMode.OpenOrCreate, FileAccess.Write))
{
       stream.CopyTo(fileStream);
}

 
 
缓存的思路
image


 

现在是思路是首先检查是否被缓存里,首先定义一个公用的缓存文件夹,在静态构造函数中创建文件夹
private const string CacheDirectory = "CachedImages";
       
        static StorageCachedImage()
        {

            //创建缓存目录
            using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (!isolatedStorageFile.DirectoryExists(CacheDirectory))
                {
                    isolatedStorageFile.CreateDirectory(CacheDirectory);
                }
            }
        }
 

然后将Url转换成文件名,我的方法比较简单直接替换’/’符号。使用FileExists判断文件是否存在
//文件路径
filePath = Path.Combine(CacheDirectory, uriSource.AbsolutePath.TrimStart('/').Replace('/', '_'));

/// <summary>
       /// 打开缓存源
       /// </summary>
       private void OpenCatchSource()
       {
           bool exist;
           using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
           {
               exist = isolatedStorageFile.FileExists(filePath);
           }
           if (exist)
           {
               SetCacheStreamSource();
           }
           else
           {
               SetWebStreamSource();
           }
       }
 

如果没有缓存则通过Uri下载图片并保存到IsolatedStorageFile。
使用httpWebRequest实现下载,使用IsolatedStorageFileStream保存图片
/// <summary>
       /// 下载Uri中的图片
       /// </summary>
       private void SetWebStreamSource()
       {
           var httpWebRequest = (HttpWebRequest)WebRequest.Create(uriSource);
           httpWebRequest.AllowReadStreamBuffering = true;
           httpWebRequest.BeginGetResponse(ResponseCallBack, httpWebRequest);
       }

       /// <summary>
       /// 下载回调
       /// </summary>
       /// <param name="asyncResult"></param>
       private void ResponseCallBack(IAsyncResult asyncResult)
       {
           var httpWebRequest = asyncResult.AsyncState as HttpWebRequest;
           if(httpWebRequest == null)return;
           try
           {
               var response = httpWebRequest.EndGetResponse(asyncResult);
               using(var stream = response.GetResponseStream())
               using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
               using (var fileStream = isolatedStorageFile.OpenFile
                   (filePath, FileMode.OpenOrCreate, FileAccess.Write))
               {
                   stream.CopyTo(fileStream);//保存到本地
               }
               Dispatcher.BeginInvoke(SetCacheStreamSource);
           }
           catch(Exception err)
           {
               Debug.WriteLine(err.Message);
           }
       }
 

保存到本地后下载,用IsolatedStorageFileStream打开本地图像流,并通过父类的SetSource设置图片流。
private void SetCacheStreamSource()
       {
           using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
           using (var stream = isolatedStorageFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
           {
               SetSource(stream);
           }

 
完整代码如下:

 using System;
using System.Diagnostics;
using System.IO;
using System.IO.IsolatedStorage;
using System.Net;
using System.Windows.Media.Imaging;

namespace KimiStudio.Controls
{
    /// <summary>
    /// 独立存储缓存的图片源
    /// </summary>
    public sealed class StorageCachedImage : BitmapSource
    {
        private readonly Uri uriSource;
        private readonly string filePath;
        private const string CacheDirectory = "CachedImages";
       
        static StorageCachedImage()
        {

            //创建缓存目录
            using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (!isolatedStorageFile.DirectoryExists(CacheDirectory))
                {
                    isolatedStorageFile.CreateDirectory(CacheDirectory);
                }
            }
        }

        /// <summary>
        /// 创建一个独立存储缓存的图片源
        /// </summary>
        /// <param name="uriSource"></param>
        public StorageCachedImage(Uri uriSource)
        {
            this.uriSource = uriSource;

            //文件路径
            filePath = Path.Combine(CacheDirectory, uriSource.AbsolutePath.TrimStart('/').Replace('/', '_'));
            OpenCatchSource();
        }

        /// <summary>
        /// 打开缓存源
        /// </summary>
        private void OpenCatchSource()
        {
            bool exist;
            using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
            {
                exist = isolatedStorageFile.FileExists(filePath);
            }
            if (exist)
            {
                SetCacheStreamSource();
            }
            else
            {
                SetWebStreamSource();
            }
        }

        /// <summary>
        /// 设置缓存流到图片
        /// </summary>
        private void SetCacheStreamSource()
        {
            using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
            using (var stream = isolatedStorageFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
            {
                SetSource(stream);
            }
        }

        /// <summary>
        /// 下载Uri中的图片
        /// </summary>
        private void SetWebStreamSource()
        {
            var httpWebRequest = (HttpWebRequest)WebRequest.Create(uriSource);
            httpWebRequest.AllowReadStreamBuffering = true;
            httpWebRequest.BeginGetResponse(ResponseCallBack, httpWebRequest);
        }

        /// <summary>
        /// 下载回调
        /// </summary>
        /// <param name="asyncResult"></param>
        private void ResponseCallBack(IAsyncResult asyncResult)
        {
            var httpWebRequest = asyncResult.AsyncState as HttpWebRequest;
            if(httpWebRequest == null)return;
            try
            {
                var response = httpWebRequest.EndGetResponse(asyncResult);
                using(var stream = response.GetResponseStream())
                using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
                using (var fileStream = isolatedStorageFile.OpenFile
                    (filePath, FileMode.OpenOrCreate, FileAccess.Write))
                {
                    stream.CopyTo(fileStream);
                }
                Dispatcher.BeginInvoke(SetCacheStreamSource);
            }
            catch(Exception err)
            {
                Debug.WriteLine(err.Message);
            }
        }
    }

  
}

 
测试
定义一个Image
Uri uriSource = new Uri(@”http://www.2cto.com/uploadfile/2012/0301/20120301094720431.png”);
image1.ImageSource = new StorageCachedImage(uriSource);
 
用IsoStoreSpy查看(这里是我APP实际的图)

  

 


摘自 Kiminozo's Tech Blog

相关文章

    暂无相关文章
相关频道:

用户评论