Forum Xamarin.Android

Adapter views disposing

In an android app when I use an adapter view, having my own adapter implementation, are the views produced destroyed by adapter class correctly disposed by xamarin, or do i need to manually dispose them

Posts

  • DWestyDWesty USMember ✭✭

    The purpose of the adapter is so that it can manage the lifecycle of the views and reuse them appropriately to limit the footprint regardless of how large the backing data is. You shouldn't need to manually dispose of them but be mindful of EventHandlers and references your views hold on to.

  • PulkitPulkit AUMember ✭✭
    edited September 2013

    I have complex controls with event handlers hooked to them, what would be the approach to unhook the event handlers, as i do not have control over the life cycle of the adapter views. Also I have adapter views inside adapter view, spinner in list control, adapters for spinners are dynamically set how should i be disposing them

  • CheesebaronCheesebaron DKInsider, University mod

    Unhook them when convertView is not null.

  • PulkitPulkit AUMember ✭✭

    Then events would stop working since I hook events once i create a view, when convert view is not null i simply set data. Removing the hooked events here will remove them while user is using the widget and scrolling it

  • CheesebaronCheesebaron DKInsider, University mod

    It is not being used if it is not displayed on the screen. So this is the correct place to unhook the event and hook up a new one.

  • PulkitPulkit AUMember ✭✭

    Lets say adaper view has created 5 views to display data, now when i scroll and the 6th item is to be displayed, the adapter view doesn't create a new view but provides me one to re use. i only set data on the view. If i unhook now then the view which is now displayed would have unhooked handler (logically wrong behaviour)

  • FZelleFZelle DEMember ✭✭✭
    edited September 2013

    While Cheesbaron is wrong on the topic it self, you should read his answer completely, he states to unhook and rehook it every time.
    This is needed if you use lambdas instead of functions.

    If you calculate the amound of controls you might have on the screen, this is ignorable.

    But what you have to do is dispose everything that implements IDisposable ( there is a reason for that ).
    So if you use a bitmap dispose it as fast as possibble.

  • PulkitPulkit AUMember ✭✭

    So if i have an adapter view, inside its GetView function ( if(convertView == null) { // create view // hook event handlers txtView.Click += something; ) the handler is same for all and would be based on data of txtView. Now tell me good place to do -= . If i hook and unhook still when i close the app the views which are in view need to have there Click handlers unhooked . I need to know how to achieve this

  • PulkitPulkit AUMember ✭✭

    Can anyone throw light on this, or shall I assume you cant have your custom adapter view with clickable items in xamarin, without causing a memory leak

  • FZelleFZelle DEMember ✭✭✭

    It is the same as everywhere in .NET.

    Implement IDisposable and use it accordingly.

  • BradleyBradley USMember ✭✭✭

    You "could" add the views to a collection so you will have a reference to each one of them and properly remove your event handlers.

    // Create a collection to store your views (class level field, init in adapter's constructor).
    JavaList<View> views = new JavaList<View>();
    
    // In the GetView method
    if(convertView == null) { 
        // create view 
        // hook event handlers 
        txtView.Click += something;
        // Only add views that you create, recycled views will already by in the collection.
        views.Add(txtView);
    }
    

    VERY IMPORTANT!!!! You will be responsible for removing the event handlers and cleaning these references up or they will leak. If you are using a ListFragment, the OnDestroyView method is where you probably would want to do this. Loop through the collection to remove handlers, then call the Clear() method on the collection to release the view references.

  • PulkitPulkit AUMember ✭✭

    Have followed this approach only, the only thing is during disposing there is a rare crash. The only difference is m using a .net list not a JavaList is there a reason to use that

  • LucaFongaroLucaFongaro USMember ✭✭
    edited October 2013

    I guess it's a big problem in c#. In Java there is setOnClickListener (also available in Monodroid, but it has the same behavior as +=). I hope Microsoft add this feature and Xamarin add it for monodroid/monotouch :-)

  • FZelleFZelle DEMember ✭✭✭

    What are you talking about?

  • PulkitPulkit AUMember ✭✭

    @Bradley Can you please clarify on why the use of JavaList and not a List. Thanks

  • BradleyBradley USMember ✭✭✭

    @Pulkit I tend to use the JavaList out of habit. In this case it isn't needed so you can use the .NET list.

    FWIW, when you do need a JavaList is when passing a list to an Android API method. Like when passing a list to an ArrayAdapter constructor. This page in the guides explains why. Read the Binding Design section.

    Here is an example that may help. It offers more control over making sure everything is cleaned up properly. It's probably overkill. The important part is cleaning up before the call to base.OnDestroyView()

        public override void OnDestroyView()
        {
            // Remove handlers and release references before calling base method.
            for (int i = 0; i < views.Count; i++)
            {
                if (views[i] != null)
                {
                    views[i] -= YourOnClickHandler;
                    views[i] = null;
                }
            }
    
            base.OnDestroyView();
        }
    
  • PulkitPulkit AUMember ✭✭

    :) great help

Sign In or Register to comment.