|
Linker设定:程序代码优化
|
不论是在Android或iOS的项目中,项目属性内都有一个Linker选项,例如下图:
Linker设定指的就是程序代码的优化,
所谓的优化就是在编译程序代码时仅编译出有使用到的对象、方法、属性及事件等,
每个选项的编译行为如下:
None 或Dont link:不进行任何的优化,通常在需要进行DeBug时或特殊需求才会选此项。
SDK Assemblies only:对Xamarin.Android 或 Xamarin.iOS的做优化 All Assemblies:最所有组件优化。
默认在DeBug模式下使用None,
Release模式下默认是SDK Assemblies only,
以Android为例,从编译出的apk档的大小可以看出很明显的差异。
使用None编译出的大小约26MB:
使用SDK Assemblies only编译出的大小约3.4MB:
因此在撰写程序代码时, 应尽量避免使用到反射的写法, 如下程序代码使用了反射的方式更改了Button的文字,使用None模式时一切正常
1 | Button button = FindViewById<Button>(Resource.Id.MyButton); |
2 | typeof(Button).GetProperty("Text").SetValue(button, "test Linker"); |
但改成SDK Assemblies only后,执行立刻就报错了
错误为NullReferenceException,因为GetProperty("Text")找不到名称为Text的属性回传了Null。
那怎样的情况这个属性才会被编译?需要出现如下代码段:
1 | button.Text = "test"; |
虽然上面的程序代码会让Text属性被编译进去, 但也只编译了Set的部分,如果用反射去Get照样会死给你看...
但如果还是得需要用到反射, 我们可以自行定义XML档案指定编译时省略哪些东西不做优化处理。 以上方的程序代码来说,我们希望Button的Text不要被优化, 而Text属性又是继承了TextView而来:
所以这里要处理的其实是Android.Widget.TextView, 而由上方的组件信息可得知组件名称
接着就可以在项目中加入Xml,并撰写以下内容:
1 | <linker> |
2 | <assembly fullname="Mono.Android"> |
3 | <type fullname="Android.Widget.TextView"></type> |
4 | </assembly> |
5 | </linker> |
assembly fullname放的就是组件名称,
type fullname里放的就是要省略优化类别名(要含NameSpace)。
接着在Android中,选择该Xml档案,
在建置动作的地方选择LinkDescription,并且重新建置项目。
如果是在iOS下,依照同样的方法取得组件名称与类别完整名称后,
一样建立Xml在项目目录下并撰写相同格式内容XML,
最后在项目属性内iOS Build→于Additional mtouch arguments输入(linker为自建目录):
--xml=${ProjectDir}/linker/setting.xml 如图
这样就可以避免程序优化导致反射无法使用,
但相对的会增加一点点编译出的程序大小(可能1~2K之类的)。
其他当然还是有方法可以避免被优化,
但要调整SDK的优化只能用此方式喔。
| 作者:Steven Chang 2015/04 |
链接:http://www.thinkpower.info/xamarin/cn/Article_19.aspx?idx=19#xamarin_top

本文详细介绍了程序代码优化的概念及其在Android和iOS项目中的应用。通过Linker设定的不同选项,可以有效减小编译出的程序大小,但同时需要注意避免使用反射的方式访问对象属性。文中提供了解决方案,通过自定义XML文件来指定哪些类不进行优化,从而避免反射使用受限的情况。此外,还展示了如何在不同平台下调整优化设置的方法。

1011

被折叠的 条评论
为什么被折叠?



