图像缓存8.1
问题描述:
我写了Windows Phone 8.1(WinRT的)应用程序。它显示从互联网获取的图像。图像缓存8.1
我想这个图像保存到本地存储,然后显示它。 我的意思是说,每次打开应用程序,它会检查如果图像是在本地存储,显示,并从平行加载互联网这个形象的新副本,并刷新用户界面,新的形象。
意味着,直到从互联网加载图像的新副本,从本地存储器获取的此图像的缓存副本将充当占位符。
但问题是我得到的空白UI直到图像加载从互联网上,而不是局部的图像作为占位符。
C#
public sealed partial class ProfileView : Page
{
const string PROFILE_PIC_FILE_NAME = "UmangProfilePic.jpg";
public ProfileView()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
//Testing:
//string url = "http://www.nokia.com/sites/default/files/styles/medium/public/media/nokia_white_logo.png"; //small image
string url = "http://anderson.chem.ox.ac.uk/images/group2015.jpg"; //large image
await UmangImageCacheAsync(url);
}
/// <summary>
/// Check if image exists in local storage, load that image to UI control
/// Then, get latest image from internet and storage that image in local storage
/// Then, load that new image from local storage again to UI control
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
private async Task UmangImageCacheAsync(string url)
{
loadingProfilePic.IsActive = true;
//var dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
//var ignored = dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() =>
//{
//});
var dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
var ignored = dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() =>
{
if (await FileExists(PROFILE_PIC_FILE_NAME))
{
profilePicImage.Source = await GetLocalImageAsync();
}
});
var result = await GetRemoteImageAsync(url);
if (result is BitmapImage)
{
profilePicImage.Source = result as BitmapImage;
loadingProfilePic.IsActive = false;
}
else
{
loadingProfilePic.IsActive = false;
}
}
private async Task<BitmapImage> GetLocalImageAsync()
// private async Task<bool> GetLocalImageAsync()
{
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFile file = await localFolder.GetFileAsync(PROFILE_PIC_FILE_NAME);
var image = await FileIO.ReadBufferAsync(file);
Uri uri = new Uri(file.Path);
return new BitmapImage(new Uri(file.Path));
//return true;
}
private static async Task<object> GetRemoteImageAsync(string url)
//private static async Task GetRemoteImageAsync(string url)
{
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFile file = await localFolder.CreateFileAsync(PROFILE_PIC_FILE_NAME, CreationCollisionOption.ReplaceExisting);
HttpClient client = new HttpClient();
try
{
byte[] responseBytes = await client.GetByteArrayAsync(url);
var stream = await file.OpenAsync(FileAccessMode.ReadWrite);
using (var outputStream = stream.GetOutputStreamAt(0))
{
DataWriter writer = new DataWriter(outputStream);
writer.WriteBytes(responseBytes);
await writer.StoreAsync();
await outputStream.FlushAsync();
}
var image = await FileIO.ReadBufferAsync(file);
Uri uri = new Uri(file.Path);
return new BitmapImage(new Uri(file.Path));
}
catch (Exception _ex)
{
return false;
}
}
public static async Task<bool> FileExists(string fileName)
{
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
try
{
StorageFile file = await localFolder.GetFileAsync(fileName);
}
catch (Exception _fileEx)
{
return false;
}
return true;
}
}
XAML:
<Grid>
<Grid>
<Image
x:Name="profilePicImage"
Width="400"
Height="400" />
<ProgressRing x:Name="loadingProfilePic"
IsActive="False"
IsEnabled="True" >
</ProgressRing>
</Grid>
</Grid>
重现此问题:首先使用 “URL”(小图)执行应用程序, 然后debugg再次使用第二网址评论第一个网址,直到 从互联网下载的新图像,第一个图像应该作为 占位符,但你会看到进步环仅
答
您的来电GetLocalImageAsync()得到调用GetRemoteImageAsync(后执行),因为你需要将它发布到调度队列。我想你想用另一种方式来完成你的场景。
感谢, 斯特凡威克 - Windows 8开发平台
你总是可以尝试使用从http://coding4fun.codeplex.com它有一个占位符的选择应该是什么新的内容的互联网加载过程中所示的SuperImage控制 – Depechie