Should I use WeakReference when keeping reference of a view in an activity?

laygrlaygr MXMember, University
edited October 2014 in Xamarin University

In order to avoid memory leaks, should I do something like this?
class AnActivity... WeakReference AButton ... OnCreate... aButton = new WeakReference(FindViewById(...

or it isn't necessary

Posts

  • JuergenKollerJuergenKoller ✭✭ DEUniversity ✭✭

    The syntax is:

    Button button = FindViewById<Button>(Resource.Id.MyButton);
    

    there is no need for 'new' in this case because it's handled by the OS. You are just referencing an item which was defined in your .axml file from the Recources/layout folder.
    I'm still learning, too and hope one of the trainer can confirm my explanation.

  • laygrlaygr MXMember, University

    @Juergen‌ I don't just want to get a reference to the button, but to maintain it through the whole activity lifecycle; that is why I wonder if I need to keep the reference through a weakrefenence.

  • JuergenKollerJuergenKoller ✭✭ DEUniversity ✭✭

    If you define it in a .axml file it's maintained by the OS.
    Not sure what you are trying to do but you can always use

    Button button = FindViewById<Button>(Resource.Id.MyButton);

    to come back to the same button. For example you could change the label from the button in your OnCreate method to 'test'.
    If you now use

    Button button = FindViewById<Button>(Resource.Id.MyButton);

    in you OnResume method it will show you 'test' for button.Text because it's the same button. Can you give us more details what exactly you are trying to do with this button?

  • laygrlaygr MXMember, University

    I only want to avoid calling FindViewById every time I need to use a view. My code would be cleaner.

  • RobGibbensRobGibbens Xamurai USMember, Xamarin Team, University, XamUProfessors, Developer Group Leader Xamurai

    A good way to avoid calling FindViewById for every view is to implement the ViewHolder pattern. This is a common pattern in the Android ecosystem, and we can use it with Xamarin.Android as well. James Montemagno has a nice writeup here giving a brief introduction to the pattern. We also discuss this in the Memory Management and Best Practices class in Xamarin University.

  • rene_ruppertrene_ruppert Xamurai DEXamarin Team, University, XamUProfessors Xamurai

    Another nice idea I have recently seen: use partial classes and split your Activity into MyActivity.cs and MyActivity.ui.cs. In there have:

    DetailsActivity.cs:
    {
    ...
    this.AddCommentButton.Clicked += (sender, e) => {};
    ...
    }

    DetailsActivity.ui.cs:

    public partial class DetailsActivity
        {
            private Button _addCommentButton;
            private ListView _commentsList;
    
            public Button AddCommentButton
            {
                get
                {
                    return _addCommentButton
                           ?? (_addCommentButton = FindViewById<Button>(Resource.Id.AddCommentButton));
                }
            }
    
            public ListView CommentsList
            {
                get
                {
                    return _commentsList
                           ?? (_commentsList = FindViewById<ListView>(Resource.Id.CommentsList));
                }
            }
    
        }
    
  • laygrlaygr MXMember, University

    @rene_ruppert That is exactly what I started doing yesterday!

  • laygrlaygr MXMember, University

    @rene_ruppert‌ You say that then one could do:
    DetailsActivity.cs: { ... this.AddCommentButton.Clicked += (sender, e) => {}; ... }
    But, wouldn't this cause a memory leak? (Because we wouldn't be able to remove the event handler).

  • rene_ruppertrene_ruppert Xamurai DEXamarin Team, University, XamUProfessors Xamurai

    @JesusGonzalez.7825‌ In this case no. Eventually the Activity will be destroyed and with it the event handler.

    The problem with Garbage Collection and events only manifests if the publisher of the event (the class that defines the event) outlives the subscriber (the class that contains the event handler). If that is the case, the publisher keeps a strong reference to the subscriber, thus making it impossible for the subscriber being collected by GC.

    In your situation the lifetime of the two is the same - they both are in the same Activity.

  • laygrlaygr MXMember, University

    @rene_ruppert Now is clear. Thanks a lot.

Sign In or Register to comment.