2016-11-09 111 views
0

我發送網絡和移動之間的文本小的Web應用程序 - 我想爲這個Web應用程序創建一個移動應用程序,並決定去與Xamarin,而不是學習Java和斯威夫特。我購買了課程並學習瞭如何使用Xamarin.Forms,並且我構建了我的第一個Alpha版本(已經發布到Play商店並且App Store版本在評論進程中)。小Xamarin.Forms應用拋出OutOfMemoryException異常在Android

模擬器上的所有開發進度都沒有問題,但是一旦我將應用程序下載到我的Nexus 6P(這是一款超級手機) - 在應用程序各部分之間移動之後,應用程序就會停止。我調試了它,發現它由於OutOfMemoryException而關閉。該應用程序只有很少的部分與一個ListView(我意識到與ListView的問題,它以某種方式使應用程序停止運行 - 而它在模擬器上運行得非常好)。

我的ViewModels(使用的HttpClient)從服務器讀出的數據,並創建其被綁定到視圖的的ObservableCollection。我的問題是與ListView,使OutOfMemory的所有問題:

<ListView.ItemTemplate> 
    <DataTemplate> 
     <ViewCell> 
      <Frame HasShadow="False" OutlineColor="White" Padding="10, 10, 10, 20" VerticalOptions="Center"> 
       <Frame.Content> 
        <Frame OutlineColor="Gray" VerticalOptions="Center"> 
         <Frame.HasShadow> 
          <OnPlatform x:TypeArguments="x:Boolean" Android="True" WinPhone="True" iOS="False" /> 
         </Frame.HasShadow> 

         <Grid> 
          <Grid.RowDefinitions> 
           <RowDefinition Height="*" /> 
           <RowDefinition Height="Auto" /> 
          </Grid.RowDefinitions> 

          <Label Grid.Row="0" FontSize="Small" 
            Text="{Binding Paste.Text}" /> 

          <Grid Grid.Row="1" Padding="0, 20, 0, 0"> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="*" /> 
            <ColumnDefinition Width="*" /> 
            <ColumnDefinition Width="*" /> 
            <ColumnDefinition Width="*" /> 
           </Grid.ColumnDefinitions> 


           <ffimageloading:CachedImage x:Name="btnCopy" Grid.Column="0" DownsampleToViewSize="true" Scale="0.8" Source="copy.png"> 
            <ffimageloading:CachedImage.GestureRecognizers> 
             <TapGestureRecognizer Command="{Binding CopyToClipboardCommand, Source={x:Reference pastesPage}}" CommandParameter="{Binding .}" /> 
            </ffimageloading:CachedImage.GestureRecognizers> 
           </ffimageloading:CachedImage> 

           <StackLayout Grid.Column="1"> 
            <ffimageloading:CachedImage x:Name="btnFavourite" DownsampleToViewSize="true" 
                   IsVisible="{Binding ShowFavouriteButton}" 
                   Scale="0.8" 
                   Source="{Binding FavouriteImage}"> 
             <ffimageloading:CachedImage.GestureRecognizers> 
              <TapGestureRecognizer Command="{Binding BindingContext.ChangePasteFavouriteCommand, Source={x:Reference pastesPage}}" CommandParameter="{Binding .}" /> 
             </ffimageloading:CachedImage.GestureRecognizers> 
            </ffimageloading:CachedImage> 
            <ActivityIndicator IsRunning="{Binding IsFavouriteRunning}" 
                 IsVisible="{Binding IsFavouriteRunning}" 
                 Scale="0.7" Color="Gray" /> 
           </StackLayout> 

           <StackLayout Grid.Column="2"> 
            <ffimageloading:CachedImage x:Name="btnDelete" DownsampleToViewSize="true" 
                   IsVisible="{Binding ShowDeleteButton}" 
                   Scale="0.8" Source="delete.png"> 
             <ffimageloading:CachedImage.GestureRecognizers> 
              <TapGestureRecognizer Command="{Binding BindingContext.DeletePasteCommand, Source={x:Reference pastesPage}}" CommandParameter="{Binding .}" /> 
             </ffimageloading:CachedImage.GestureRecognizers> 
            </ffimageloading:CachedImage> 
            <ActivityIndicator IsRunning="{Binding IsDeleteRunning}" 
                 IsVisible="{Binding IsDeleteRunning}" 
                 Scale="0.7" Color="Gray" /> 
           </StackLayout> 

           <ffimageloading:CachedImage x:Name="btnShare" Grid.Column="3" DownsampleToViewSize="true" Scale="0.8" Source="share.png"> 
            <ffimageloading:CachedImage.GestureRecognizers> 
             <TapGestureRecognizer Command="{Binding SharePasteCommand, Source={x:Reference pastesPage}}" CommandParameter="{Binding .}" /> 
            </ffimageloading:CachedImage.GestureRecognizers> 
           </ffimageloading:CachedImage> 
          </Grid> 
         </Grid> 
        </Frame> 
       </Frame.Content> 
      </Frame> 
     </ViewCell> 
    </DataTemplate> 
</ListView.ItemTemplate> 

這些圖標是非常小的PNG文件。這個列表並不大,我不認爲一個小的ListView應該拋出這樣的異常。這裏有什麼問題?我該如何解決這個問題?

我試圖刪除圖標和同樣的問題發生,我試圖改變從圖像圖標添加到FontAwesome圖標,但應用程序很快停止。我甚至試圖使用ChacheImages插件,但沒有任何幫助。

這裏是產生的列表中的形象: enter image description here

有什麼建議?

感謝, 賽義夫。

+0

你應該檢查你的圖像大小。大圖像造成問題。 –

+0

圖像太小 - 約1.0 KB。我也嘗試刪除這些圖像,並使用FontAwesome中的符號,並且它們沒有幫助,並且引發了OutOfMemoryException。 – iseif

回答

1

你提到的關鍵部分是,這通過您的應用程序的不同部分移動之後發生。這意味着你有一個內存泄漏的地方,由導航觸發。

一個常見原因是訂閱事件頁面上顯示,從來沒有取消訂閱或以其他方式保持整個內存頁,而導航代碼不斷創造新的頁面實例。 沒有看所有的代碼,很難確切地說出問題出在哪裏。

另請注意,您的XAML太複雜了。你應該總是努力保持控制嵌套儘可能低。然而在這裏你有兩個框架,兩個網格和堆棧佈局,都嵌套。這是可怕的爲您的應用程序性能。請考慮簡化您的佈局。有許多技術來完成這一點。只要你可以,使用一個簡單的AbsoluteLayout並根據需要按比例調整控件的大小以顯示數據。

+0

在列表頁面中,我只使用綁定到命令的TapGestureRecognizer,並且此頁面有一個MessagingCenter.Subscribe,我也清除頁面OnDisappearing()方法的列表和所有內容。和OnAppearing()方法我刪除了Navigation.NavigationStack上的所有頁面。但所有這些都無濟於事 - 我在List中更新了這個問題。這並不複雜。 – iseif

+0

你打電話給MessagingCenter嗎?退出頁面時取消訂閱?這是可能消耗你的記憶的東西之一。 – irreal

+0

關於列表,無論它在屏幕上出現多麼複雜都無關緊要,您的XAML **的複雜性遲早會導致問題,因此請考慮簡化XAML。這並不意味着視覺效果必須改變。它可以看起來完全相同,嵌套控件較少 – irreal