Linker设定:程序代码优化

来源:互联网 发布:淘宝付了定金不想要了 编辑:程序博客网 时间:2024/06/01 21:31

Linker设定:程序代码优化

不论是在Android或iOS的项目中,项目属性内都有一个Linker选项,例如下图:

Android:  

iOS:


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模式时一切正常

view sourceprint?
1Button button = FindViewById<Button>(Resource.Id.MyButton);
2typeof(Button).GetProperty("Text").SetValue(button, "test Linker");

但改成SDK Assemblies only后,执行立刻就报错了


错误为NullReferenceException,因为GetProperty("Text")找不到名称为Text的属性回传了Null。

那怎样的情况这个属性才会被编译?需要出现如下代码段:

1button.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的优化只能用此方式喔。

相关下载
  • 范例文件下载
    https://github.com/ThinkPowerXamarin/Xamarin.Linker
参考信息
  • Xamarin iOS-Linker
  • Xmarin Android-Linker
  • 客制化Linker
作者:Steven Chang 2015/04

链接:http://www.thinkpower.info/xamarin/cn/Article_19.aspx?idx=19#xamarin_top

0 0
原创粉丝点击