enisn / Xamarin.Forms.InputKit

CheckBox, Radio Button, Labeled Slider, Dropdowns etc.
MIT License
586 stars 100 forks source link

Advanced Entry Icon Image won't display in release on Maui Android #370

Open jmichas opened 1 month ago

jmichas commented 1 month ago

Describe the bug When setting the icon of the entry using a FontImageSource everything works fine in debug builds but in release the icon's don't display. I thought this might be a linker issue but it appears not or there is something else that the default release build is doing.

I get these errors in the Android log:

java.io.FileNotFoundException: /MyProject.Controls.FontImageSource: open
failed: ENOENT (No such file or directory)
    at libcore.io.IoBridge.open(IoBridge.java:574)
    at java.io.FileInputStream.<init>(FileInputStream.java:160)
    at java.io.FileInputStream.<init>(FileInputStream.java:115)
    at android.content.ContentResolver.openInputStream(ContentResolver.java:1526)
    at
com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResourceFromUri(StreamLocalUriFetcher.java:74)
    at
com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResource(StreamLocalUriFetcher.java:50)
    at
com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResource(StreamLocalUriFetcher.java:13)
    at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:44)
    at
com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:100)
    at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:95)
    at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:88)
    at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:311)
    at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:280)
    at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:235)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
    at
com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:424)
    at java.lang.Thread.run(Thread.java:1012)
    at
com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultPriorityThreadFactory$1.run(GlideExecutor.java:383)
Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
    at libcore.io.Linux.open(Native Method)
    at libcore.io.ForwardingOs.open(ForwardingOs.java:563)
    at libcore.io.BlockGuardOs.open(BlockGuardOs.java:274)
    at libcore.io.ForwardingOs.open(ForwardingOs.java:563)
    at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:8063)
    at libcore.io.IoBridge.open(IoBridge.java:560)
    at java.io.FileInputStream.<init>(FileInputStream.java:160) 
    at java.io.FileInputStream.<init>(FileInputStream.java:115) 
    at android.content.ContentResolver.openInputStream(ContentResolver.java:1526) 
    at
com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResourceFromUri(StreamLocalUriFetcher.java:74) 
    at
com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResource(StreamLocalUriFetcher.java:50) 
    at
com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResource(StreamLocalUriFetcher.java:13) 
    at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:44) 
    at
com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:100) 
    at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:95) 
    at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:88) 
    at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:311) 
    at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:280) 
    at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:235) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) 
    at
com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:424) 
    at java.lang.Thread.run(Thread.java:1012) 
    at
com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultPriorityThreadFactory$1.run(GlideExecutor.java:383) 

To Reproduce Steps to reproduce the behavior:

  1. Add an Advanced Entry to a page with a font icon image source
  2. Put an image with it using the same font image source
  3. Build using release config and view on emulator or physical device.
  4. You will see no icon for the entry field but the image tag will display the icon.
  5. In debug both will display

Expected behavior Icon should be displayed

jmichas commented 1 month ago

Well, I pulled down the code for the Advanced Entry and decided to fiddle with it myself. When I ran it locally with an emulator in debug mode, the icons didn't display so not sure how or why they worked with the nuget package.

From what I can see it should never have worked in the first place. The imgIcon field that is setup as a placeholder is never wired up to the bindable property for IconImage. It needs to be treated like the Text property.

So I added into the ctor: imgIcon.SetBinding(Image.SourceProperty, new Binding(nameof(IconImage), source: this));

and changed the IconImage property to use the backing bindable IconImageProperty changing the type of the bindable from string to ImageSource

public ImageSource IconImage
{
    get => (ImageSource)GetValue(IconImageProperty);
    set
    {
        imgIcon.IsVisible = value != null;
        SetValue(IconImageProperty, value);
    }
}