0

I have a Xamarin.Forms NavigationPage and I noticed that after pushing quite a lot of pages (say 20), the app starts being laggy and might freeze at some point. I'm guessing it must be using a lot of memory (I should really check in Android's monitoring tools now that I thought about it).

Is there another way I can provide a history functionality (so, the user can always press back to go to where they were reading before) that doesn't eat up all the memory? I know it's possible because it's done in other apps.

SpaceMonkey
  • 4,143
  • 5
  • 38
  • 60
  • And what kind of data is on those pages? Just text? Images? How many and what is the size of these images? Maybe it is an idea to check the memory your app uses, navigate to the next page, see what that does to your memory usage and repeat a couple of times? To be sure that is *is* indeed the navigation stack. – Gerald Versluis Jul 02 '15 at 08:06
  • Well, this happened only when I started using the NavigationPage, before that I wasn't saving old pages, just replacing them. My pages are all listviews with a lot of text and a few images. The images are supposed to be cached on the disk. – SpaceMonkey Jul 02 '15 at 08:16
  • 1
    According to this link; http://forums.xamarin.com/discussion/40323/out-of-memory-error-with-navigation-page it is a known bug. There is also a possible workaround given. – Gerald Versluis Jul 02 '15 at 08:21

1 Answers1

2

For solutions with multiple pages and large navigation stack You could use PagesFactory:

public static class PagesFactory
{
    static readonly Dictionary<Type, Page> pages = new Dictionary<Type, Page>();

    static NavigationPage navigation;
    public static NavigationPage GetNavigation()
    {
        if (navigation == null)
        {
            navigation = new NavigationPage(PagesFactory.GetPage<Views.MainMenuView>());
        }
        return navigation;
    }

    public static T GetPage<T>(bool cachePages = true) where T : Page
    {
        Type pageType = typeof(T);

        if (cachePages)
        {
            if (!pages.ContainsKey(pageType))
            {
                Page page = (Page)Activator.CreateInstance(pageType);
                pages.Add(pageType, page);
            }

            return pages[pageType] as T;
        }
        else
        {
            return Activator.CreateInstance(pageType) as T;
        }
    }

    public static async Task PushAsync<T>() where T : Page
    {
        await GetNavigation().PushAsync(GetPage<T>());
    }

    public static async Task PopAsync()
    {
        await GetNavigation().PopAsync();
    }

    public static async Task PopToRootAsync()
    {
        await GetNavigation().PopToRootAsync();
    }

    public static async Task PopThenPushAsync<T>() where T : Page
    {
        await GetNavigation().PopAsync();
        await GetNavigation().PushAsync(GetPage<T>());
    }
}
Daniel Luberda
  • 7,374
  • 1
  • 32
  • 40