Search code examples
xamarin.formsembedded-resource

Using Resource from another Project in Xamarin.Forms


I've been developing a custom UI element in Xamarin.Forms which has 2 images binded properties. The UI element itself does not have any image, so I have to provide it externally.

I tried many things but its not working. Finally I made it by using images in the android project (in Resources\drawable folder) but when I change the images, I have an error.

Throwing OutOfMemoryError "Failed to allocate a 20266212 byte allocation
with 12787592 free bytes and 12MB until OOM" load image from file

and my code:

     <StackLayout Grid.Row="1">
            <customelements:CustomImageButton
                x:Name="btnReadout"
                ButtonText="Read"               
                ImageButton_Tapped="CustomImageButton_ImageButton_Tapped"                                       
                DisabledImageSource="read_disabled.png"
                EnabledImageSource="read_enabled.png"                                         
                IsButtonActive="True"
                />
        </StackLayout>

and in the my bindable property event, I call like

button.BackgroundImage = ImageSource.FromFile(enabledImageSource);

or

button.BackgroundImage = ImageSource.FromFile(disabledImageSource);

If I change the property which is IsButtonActive, several times then I got the exception above. As I understand, somehow its not cleaned from the memory and it is using path instead of direct resource.

PS: The resources have been set as android resource and I am using a real device and the image size is 27 kb


Solution

  • Your OutOfMemoryError is unrelated to bindings. It is related to the size of the images (pixels and/or bytes). More information on OOM found here.

    You might find useful using the Garbage Collection. More information on it found here.

    It sounds like your code is loading the same two images over and over again into memory without disposing them (hence making use of the Garbage Collection might be useful). Alternatively, you may be better off creating static objects containing the images you want to display. For example:

    private static FileImageSource enabledImageSource = ImageSource.FromFile("enabledImage");
    private static FileImageSource disabledImageSource = ImageSource.FromFile("disabledImage"); 
    
    /* --- Further down the code --- */
    
    private void EnableView(bool enable)
    {
        button.BackgroundImage = 
            enable ?
            enabledImageSource :
            disabledImageSource;
    }
    

    What I have done here, is created only tow instances of the enable/disable images. I am then calling those instances to prevent creating new instances of the same images over and over again.