将一个项目中的图片存到另一个项目中_Xamarin项目程序集引用资源的分析

9cec506dd07e8139bb52f5053e88b9b5.png

介绍

本编文章分为2节,第1节是介绍项目中遇到的业务场景问题,第2节是分析以及解决该业务场景问题的方法。


Part 1 业务场景中遇到的问题

本次文章中使用的Github的一个Xamarin.Forms的代码Demo是 abdulrahmanelfeky/SkiaPulse-Xamarin.Forms ,作者使用SkiaSharp完成了一个在Forms中调用XAML界面控件 ,就能在Android与iOS中显示一个律动界面控件的效果。

在尝试将这个Demo写成 .Net Standard 类库时遇到了几个问题。当我将该Demo中的核心业务逻辑的Pulse.cs文件放到 .Net Standard 中成功编译并在另一个新建的空项目中运行时,律动的效果正常地出现了,但是在XAML指定了的图片却没有出现。


Part 2 问题的分析及解决方法

XAML中涉及到图片的显示是Source属性

<SkiaPulse:Pulse Source="SkiaPulse.Images.wifi_icon.png" AutoStart="true" PulseColor="#8e44ad" Margin="50" Speed="10"/>

而源码中的OnPropertyChanged函数内含有处理Source属性的业务逻辑

            if (propertyName == nameof(Source))
            {
                string resourceID =  Source;
                Assembly assembly = GetType().GetTypeInfo().Assembly;
                using (Stream stream = assembly.GetManifestResourceStream(resourceID))
                {
                    if (stream != null)
                        resourceBitmap = SKBitmap.Decode(stream);

                }
                resourceBitmap = resourceBitmap?.Resize(new SKImageInfo(90, 90), SKFilterQuality.Medium);
            }

而图片的数据会以二进制格式存到Stream中,所以一开始我的思路是直接使用Forms提供的 Embedded images 来获取图片的Stream数据。

ImageSource.FromResource 函数返回的结果是一个 StreamImageSource 类型,其中就包含了名为 Stream 的属性,但是该属性是一个 Func 类型,当我调用该属性的Invoke函数时,结果得到的却是Null。

而官方在Xamarin论坛上说过其实Xamarin中无法从ImageSouce得到图片的Stream。


重新整理一下调用的思路,如图:

8ff41395159743f3c6c12d6f5a7fdb89.png
调用顺序

回到作者的源码中,结合两行代码分析:

Assembly assembly = GetType().GetTypeInfo().Assembly;//运行时获得本程序集
Stream stream = assembly.GetManifestResourceStream(resourceID)//从本程序集通过资源ID获得Stream

在程序运行的时候,Assembly assembly = GetType().GetTypeInfo().Assembly;获取到的程序集是图中的左边第一个DLL,而图片是在做业务开发的时候添加到图中中间的Forms DLL中,所以Stream stream = assembly.GetManifestResourceStream(resourceID)是无法获取到图片的数据的。

那我们需要怎样在图中左边第一个DLL中获取到图中中间DLL的图片呢?传参。

回到微软的Xamarin文档 Embedded images 中看到

In this example the resource ID is WorkingWithImages.beach.jpg. 
The IDE has generated this default by concatenating the Default Namespace for this project with the filename, 
using a period (.) between each value.

我们在做业务开发时添加到Forms层的图片名称,含有命名空间(Namespace)。

而有了命名空间,就可以通过反射,获取到该命名空间的程序集相关信息。


通过 . 符号对参数resourceID进行分割后,数组中的第0个数据就是我们程序集的名字。

这时候通过Assembly的 Load 函数加载出Forms DLL的程序集就可以获取到图片数据了。


原作者 App 代码参看:

abdulrahmanelfeky/SkiaPulse-Xamarin.Forms

调用Nuget的代码参看:

jingliancui/XamarinFormsSkiaPulseSample

Nuget包:

Install-Package XamarinLibrary.Xamarin.Forms.SkiaPulse -Version 1.0.0

微信公众号 :

Xamarin Library

QQ群:

313308215

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值