0

I have a small web app for sending texts between web and mobile - I wanted to create a mobile apps for this web app and decided to go with Xamarin instead of learning both Java and Swift. I bought courses and learned how yo use Xamarin.Forms and I built my first Alpha version (which already released it to the Play Store and the App Store version is in the Review progress).

All the development progress went very well on the Emulator with no issues, but once I downloaded the app to my Nexus 6P (which is a super phone) - after moving between sections on the app, the app stopped. I debugged it and found that it is closing because of OutOfMemoryException. The app only have very few sections with a ListView (I realized that the issue with the ListView which somehow makes the app stop running - while it is running very well on the emulator).

My ViewModels read the data from the server (using HttpClient) and creates the ObservableCollection which is binded to the views. My issue is with the ListView which makes all the problem with the 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>

The icons are very small png files. This list is not large and I don't think that a small ListView should throw such an exception. What is wrong here? How can I fix this issue?

I tried to remove the icons and the same issue happen, I tried to change the icons from images to a FontAwesome icons but the app stopped very quickly. I even tried to use the ChacheImages plugin but with no help.

Here is an image of the list that is produced: enter image description here

Any suggestions?

Thanks, Seif.

2
  • You should check your image size. big images cause problems. Commented Nov 9, 2016 at 10:49
  • The images are too small - about 1.0 KB. I also tried to remove the images and use symbols from FontAwesome and the same, it does not help and OutOfMemoryException has been thrown. Commented Nov 9, 2016 at 10:55

1 Answer 1

1

The key part you mentioned is that this occurs after moving through the different sections of your app. This implies you have a memory leak somewhere which gets triggered by navigation.

One common cause is subscribing to events on page appear and never unsubscribing or otherwise keeping whole pages in memory while the navigation code keeps creating new page instances. Without looking at all of your code, it's hard to say exactly where the problem is.

Also note that your XAML is way too complex. You should always strive to keep control nesting as low as possible. Yet here you have two frames, two grids and stack layouts, all nested. This is terrible for your app performance. Please consider simplifying your layout. There's numerous techniques to accomplish this. Whenever you can, use a simple AbsoluteLayout and proportionally size the controls as needed to display your data.

Sign up to request clarification or add additional context in comments.

4 Comments

In the list page I use only TapGestureRecognizer that is binded to a command and this page has one MessagingCenter.Subscribe, I also clear the list and all the Content of the page OnDisappearing() method. And OnAppearing() method I remove all the Pages on the Navigation.NavigationStack. But all of this does not help - I updated the question with the List how it appears. It is not complicated at all.
Do you call MessagingCenter.Unsubscribe when transitioning away from a page? That's one of the things that could be eating up your memory.
Regarding the list, it does not matter how complex it appears on the screen, the complexity of your XAML will cause problems sooner or later, so do consider simplifying the XAML. It doesn't mean the visuals have to change. It can look exactly the same with less nested controls
I used to fix it by optimizing the code and the XAML. thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.