小型Xamarin.Forms应用程序在Android

时间:2016-11-09 09:35:02

标签: xamarin xamarin.forms

我有一个小型网络应用程序,用于在网络和移动设备之间发送文本 - 我想为这个网络应用程序创建一个移动应用程序,并决定使用Xamarin,而不是学习Java和Swift。我买了课程并学会了如何使用Xamarin.Forms和我构建了我的第一个Alpha版本(已经将它发布到Play商店,而App Store版本正处于评论进程中)。

所有开发进度在模拟器上都没有问题,但是一旦我将应用程序下载到我的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

有什么建议吗?

谢谢, 赛福

1 个答案:

答案 0 :(得分:1)

您提到的关键部分是在浏览应用的不同部分后发生这种情况。这意味着你有一个由导航触发的内存泄漏。

一个常见原因是订阅页面上的事件,并且在导航代码不断创建新页面实例时,永远不会取消订阅或以其他方式将整个页面保留在内存中。 如果不查看所有代码,就很难确切地说出问题所在。

另请注意,您的XAML过于复杂。您应该始终努力保持控制嵌套尽可能低。然而,这里有两个框架,两个网格和堆栈布局,全部嵌套。对于您的应用效果,这是糟糕。请考虑简化您的布局。有很多技术可以实现这一目标。只要你可以,使用一个简单的AbsoluteLayout并根据需要按比例调整控件的大小,以显示你的数据。