代码改变世界

ImageLoader(多线程网络图片加载)+本地缓存 for windowsphone 7

2013-12-23 22:10  fat___lin  阅读(1287)  评论(0编辑  收藏  举报

搞了好长一阵子wp,做点好事。

C/S手机app中应用最多的是  获取网络图片,缓存到本地,展示图片

本次主要对其中的delay:LowProfileImageLoader进行修改,在获取图片的时候,加入本地缓存,和弱引用。

demo截图:

  

缓存相关:

1,App.xml.cs文件中通过IsolatedStorageFile创建缓存图片用的文件夹

// 应用程序启动(例如,从“开始”菜单启动)时执行的代码
        // 此代码在重新激活应用程序时不执行
        private void Application_Launching(object sender, LaunchingEventArgs e)
        {
            string imageCacheDriectory = "ImagesCache";
            using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (store.DirectoryExists(imageCacheDriectory) != true)
                {
                    store.CreateDirectory(imageCacheDriectory);
                }
            }
        }
View Code

2,LowProfileImageLoader.cs中 image在uri修改的事件中加入判断,如果本地已经缓存图片文件,直接读取本地;如果本地没有缓存,则通过网络获取,并缓存到本地

 private static void OnUriSourceChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            var image = (Image)o;
            var uri = (Uri)e.NewValue;

            if (!IsEnabled || DesignerProperties.IsInDesignTool)
            {
                // Avoid handing off to the worker thread (can cause problems for design tools)
                image.Source = new BitmapImage(uri);
            }
            else
            {
                using (var store = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    string imageCacheFileName = App.IMAGECACHEDIRECTORY + ToInternalKey(uri.ToString());

                    if (store.FileExists(imageCacheFileName))
                    {
                        // check local image file
                        BitmapImage bitmapImage = new BitmapImage();
                        using (var imageStream = store.OpenFile(imageCacheFileName, FileMode.Open, FileAccess.Read))
                        {
                            bitmapImage.SetSource(imageStream);
                        }
                        WeakReference<BitmapImage> mybitimage = new WeakReference<BitmapImage>(bitmapImage);
                        image.Source = mybitimage.Target;
                    }
                    else
                    {
                        // Clear-out the current image because it's now stale (helps when used with virtualization)
                        image.Source = null;
                        lock (_syncBlock)
                        {
                            // Enqueue the request
                            _pendingRequests.Enqueue(new PendingRequest(image, uri));
                            Monitor.Pulse(_syncBlock);
                        }
                    }
                }
            }
        }

        static String ToInternalKey(String value)
        {
            if (String.IsNullOrEmpty(value))
            {
                return String.Empty;
            }
            String exName = value.Substring(value.LastIndexOf('.'));
            
            byte[] bytes = UTF8Encoding.GetBytes(value);
            return Convert.ToBase64String(bytes) + exName;
        }
        private static readonly Encoding UTF8Encoding = Encoding.UTF8;
View Code

3,Mainpage.xmal.cs中 相应清除缓存按钮事件中。查找缓存图片的文件夹,找到所有文件并逐个删除。(注:清除缓存图片过程中不能直接删除文件夹,且在移除的过程中要注意相关路劲是否正确,否则缓存并没有移除成功)

 /// <summary>
        /// 清除缓存
        /// </summary>
        private void btn_clear_Click(object sender, RoutedEventArgs e)
        {
            using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (store.DirectoryExists("ImagesCache") == true)
                {
                    string[] filelist = store.GetFileNames("ImagesCache/");
                    foreach (string st in filelist)
                    {
                        store.DeleteFile("ImagesCache/"+st);
                    }
                }
            }
            MessageBox.Show("图片缓存清理完毕");
            if (images != null)
                images.Clear();
        }
View Code

 

核心的获取网络代码是 微软一个叫所写的demo中所摘取,

其作用是:

在应用后台开多一个线程用于获取网络图片,优化ui线程。简化相关开发代码。

具体见:

http://blogs.msdn.com/b/delay/archive/2010/09/02/keep-a-low-profile-lowprofileimageloader-helps-the-windows-phone-7-ui-thread-stay-responsive-by-loading-images-in-the-background.aspx?Redirected=true

http://blogs.msdn.com/b/delay/archive/2010/09/08/never-do-today-what-you-can-put-off-till-tomorrow-deferredloadlistbox-and-stackpanel-help-windows-phone-7-lists-scroll-smoothly-and-consistently.aspx

 

第一次写博客,欢迎大神拍砖

 

下载demo请戳:https://files.cnblogs.com/fatlin/ImageLoader.rar