2017-02-16 16 views
2

私はWindows Phone 8.1(WINRT)アプリケーションを作成しています。 インターネットからの画像を表示します。Windows Phone 8.1のイメージキャッシュ

このイメージをローカルストレージに保存して表示します。 私が言っていることは、アプリが開くたびに、画像がローカルストレージにあるかどうかを確認し、それを表示し、インターネットからこの画像の新しいコピーを並列にロードし、uiを新しい画像に更新することです。

画像の新しいコピーがインターネットから読み込まれるまでは、ローカルストレージから取得したこの画像のキャッシュコピーは、のようになります。

しかし、プレースホルダとして機能するローカルイメージではなく、インターネットからイメージが読み込まれるまで、空白の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第使用URL インターネットから新しい画像をダウンロードするまでの最初のURLをコメントするURL、最初の画像は プレースホルダとして機能していますが、ディスパッチャキューに掲載されているので、何を観察することは、進捗リングGetLocalImageAsyncにのみ

+0

あなたはいつもそれが新しいコンテンツのインターネットのロード中に表示すべきか、プレースホルダオプションを持っているhttp://coding4fun.codeplex.comからSuperImageコントロールを使用して試みることができます – Depechie

答えて

1

あなたの呼び出し()GetRemoteImageAsync(への呼び出し後に実行されます)です。私はあなたのシナリオを達成するためにこれを逆にしたいと思う。

おかげで、 ステファンウィック - Windowsの開発プラットフォーム

関連する問題