2016-11-09 114 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