Xamarin.Android,Xamarin.iOS, Linking
Xamarin.Android applications use a linker in order to reduce the size of the application. The linker employes static analysis of your application to determine which assemblies are actually used, which types are actually used, and which members are actually used. The linker then behaves like a garbage collector, continually looking for the assemblies, types, and members that are referenced until the entire closure of referenced assemblies, types, and members is found. Then everything outside of this closure is discarded.
For example, the Hello, Android sample:
| Configuration | 1.2.0 Size | 4.0.1 Size |
| Release without Linking: | 14.0 MB | 16.0 MB |
| Release with Linking: | 4.2 MB | 2.9 MB |
Linking results in a package that is 30% the size of the original (unlinked) package in 1.2.0, and 18% of the unlinked package in 4.0.1.
Control
Linking is based on static analysis. Consequently, anything that depends upon the runtime environment won't be detected:
// To play along at home, Example must be in a different assembly from MyActivity.
public class Example {
// Compiler provides default constructor...
}
[Activity (Label="Linker Example", MainLauncher=true)]
public class MyActivity {
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Will this work?
var o = Activator.CreateInstance (typeof (ExampleLibrary.Example));
}
}
Linker Behavior
The primary mechanism for controlling the linker is the Linker Behavior drop-down within the Project Options dialog box. There are three options:
- Don't Link
- Link SDK Assemblies
- Link All Assemblies
The Don't Link option turns off the linker; the above "Release without Linking" application size used this behavior. This is useful for troubleshooting runtime failures, to see if the linker is responsible.
The Link SDK Assemblies option only links assemblies that come with Xamarin.Android. All other assemblies are not linked.
The Link All Assemblies option links all assemblies.
The above example will work with the Don't Link and Link SDK Assemblies options, and will fail with the Link All Assemblies behavior, generating the following error:
E/mono (17755): [0xafd4d440:] EXCEPTION handling: System.MissingMethodException: Default constructor not found for type ExampleLibrary.Example.
I/MonoDroid(17755): UNHANDLED EXCEPTION: System.MissingMethodException: Default constructor not found for type ExampleLibrary.Example.
I/MonoDroid(17755): at System.Activator.CreateInstance (System.Type,bool) <0x00180>
I/MonoDroid(17755): at System.Activator.CreateInstance (System.Type) <0x00017>
I/MonoDroid(17755): at LinkerScratch2.Activity1.OnCreate (Android.OS.Bundle) <0x00027>
I/MonoDroid(17755): at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (intptr,intptr,intptr) <0x00057>
I/MonoDroid(17755): at (wrapper dynamic-method) object.95bb4fbe-bef8-4e5b-8e99-ca83a5d7a124 (intptr,intptr,intptr) <0x00033>
E/mono (17755): [0xafd4d440:] EXCEPTION handling: System.MissingMethodException: Default constructor not found for type ExampleLibrary.Example.
E/mono (17755):
E/mono (17755): Unhandled Exception: System.MissingMethodException: Default constructor not found for type ExampleLibrary.Example.
E/mono (17755): at System.Activator.CreateInstance (System.Type type, Boolean nonPublic) [0x00000] in <filename unknown>:0
E/mono (17755): at System.Activator.CreateInstance (System.Type type) [0x00000] in <filename unknown>:0
E/mono (17755): at LinkerScratch2.Activity1.OnCreate (Android.OS.Bundle bundle) [0x00000] in <filename unknown>:0
E/mono (17755): at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (IntPtr jnienv, IntPtr native__this, IntPtr native_savedInstanceState) [0x00000] in
<filename unknown>:0
E/mono (17755): at (wrapper dynamic-method) object:95bb4fbe-bef8-4e5b-8e99-ca83a5d7a124 (intptr,intptr,intptr)
PreserveAttribute
The Android.Runtime.PreserveAttribute can be used to explicitly add members to be preserved by the linker, and should be placed on a member when the linker would otherwise remove it. Thus, for the above example to work, we could either place [Preserve] on the constructor:
public class Example {
[Android.Runtime.Preserve]
public Example ()
{
}
}
Or we could use [Preserve(AllMembers=true)] on the type to preseve all members. This is also useful for XML serialization:
[Android.Runtime.Preserve(AllMembers=true)]
class Example {
// Compiler provides default constructor...
}
falseflag
If the [Preserve] attribute can't be used, it is often useful to provide a block of code so that the linker believes that the type is used, while preventing the block of code from being executed at runtime. To make use of this technique, we could do:
[Activity (Label="Linker Example", MainLauncher=true)]
class MyActivity {
#pragma warning disable 0219, 0649
static bool falseflag = false;
static MyActivity ()
{
if (falseflag) {
var ignore = new Example ();
}
}
#pragma warning restore 0219, 0649
// ...
}
linkskip
It is possible to specify that a set of user-provided assemblies should not be linked at all, while allowing other user assemblies to be skipped with the Link SDK Assemblies behavior by using the AndroidLinkSkip MSBuild property:
<PropertyGroup>
<AndroidLinkSkip>Assembly1;Assembly2</AndroidLinkSkip>
</PropertyGroup>
Custom Attributes
When an assembly is linked, the following custom attribute types will be removed from all members:
- System.ObsoleteAttribute
- System.MonoDocumentationNoteAttribute
- System.MonoExtensionAttribute
- System.MonoInternalNoteAttribute
- System.MonoLimitationAttribute
- System.MonoNotSupportedAttribute
- System.MonoTODOAttribute
- System.Xml.MonoFIXAttribute
When an assembly is linked, the following custom attribute types will be removed from all members in Release builds:
- System.Diagnostics.DebuggableAttribute
- System.Diagnostics.DebuggerBrowsableAttribute
- System.Diagnostics.DebuggerDisplayAttribute
- System.Diagnostics.DebuggerHiddenAttribute
- System.Diagnostics.DebuggerNonUserCodeAttribute
- System.Diagnostics.DebuggerStepperBoundaryAttribute
- System.Diagnostics.DebuggerStepThroughAttribute
- System.Diagnostics.DebuggerTypeProxyAttribute
- System.Diagnostics.DebuggerVisualizerAttribute
Xamarin.Android,Xamarin.iOS, Linking的更多相关文章
- Xamarin.Android之简单的抽屉布局
0x01 前言 相信对于用过Android版QQ的,应该都不会陌生它那个向右滑动的菜单(虽说我用的是Lumia) 今天就用Xamarin.Android实现个比较简单的抽屉布局.下面直接进正题. 0x ...
- Xamarin.Android 反复报 Please Download android_m2repository_rxx.zip 的解决办法
我原来一直用的是老版本的 Xamarin , android_m2repository_rxx.zip 早已在 C:\Users\XXX\AppData\Local\Xamarin\Android.S ...
- Xamarin For Visual Studio 3.0.54.0 完整离线破解版(C# 开发Android、IOS工具 吾乐吧软件站分享)
Xamarin For Visual Studio就是原本的Xamarin For Android 以及 Xamarin For iOS,最新版的已经把两个独立的插件合并为一个exe安装包了.为了区分 ...
- Xamarin Mono For Android 4.6.07004 完整离线安装破解版(C#开发Android、IOS工具)
Xamarin是由Miguel de Icaza成立的一家新的独立公司,目的是给Mono一个继续奋斗的机会.Mono for Android (原名:MonoDroid)可以让开发人员使用 Mic ...
- Xamarin Mono 环境搭建(使用Visual Studio 2013 开发android 和 ios )
本文主要介绍Xamarin结合VS2013来开发Android应用程序,主要会介绍Mono和Xamarin的关系,以及整个搭建环境的过程. 一.Mono和Xamarin介绍 1.Mono简介 Mono ...
- ComponentOne Xuni助力Xamarin开发者突破百万,快速开发Android、IOS Apps
在微软Build 2015上,随着VS 2015的预览版发布,Xamrine免费版已经作为VS 2015跨平台移动解决方案的核心.与此同时,Xamarin官方也宣布其用户量达到百万之多.2011年7月 ...
- Xamarin.Android 4.10.01068 & Xamarin.iOS 1.8.361
Xamarin.Android 4.10.01068 & Xamarin.iOS 1.8.361 NEW support for Visual Studio 2013 & Portab ...
- 张高兴的 Xamarin.Forms 开发笔记:为 Android 与 iOS 引入 UWP 风格的汉堡菜单 ( MasterDetailPage )
所谓 UWP 样式的汉堡菜单,我曾在"张高兴的 UWP 开发笔记:汉堡菜单进阶"里说过,也就是使用 Segoe MDL2 Assets 字体作为左侧 Icon,并且左侧使用填充颜色 ...
- Xamarin.Form与Xamarin.Android或Xamarin.IOS的区别简述
Xamarin.Form与Xamarin.Android或Xamarin.IOS的区别简述: 可能刚刚接触Xamarin的人来说,对于这个概念比较的模糊,认为这说的不都是同一个东西吗?事实并不是这样的 ...
随机推荐
- python版本管理工具pyenv和包管理工具pipenv
一.pyenv版本管理工具 pyenv是一个python版本管理工具,可以实现轻松切换多个python版本 它可根据每个用户更改全局python版本,也可以为每个项目指定python版本,还可以管理v ...
- Linux:安装mysql
#install mysql$ rpm -ivh MySQL-client-5.5.28-1.rhel5.x86_64.rpm --nodeps$ rpm -ivh MySQL-server-5.5. ...
- 使用android模拟器开发程序
自从android studio升级到3.0之后自带的模拟器已经很好用了,尤其是升级后可以想vmware那样休眠,再次开启就可以快速启动了 以下是几点可以更方便地使用系统模拟器进行开发的小技巧,毕竟模 ...
- 洛谷P2613有理数取余
传送门 #include <iostream> #include <cstdio> #include <cstring> #include <algorith ...
- TcxGrid 调整列位置的事件
- IdentityServer4使用EFCore生成MySql时的小bug
EFCore生成PersistedGrantDbContextModelSnapshot的时候发现 b.Property<string>("Data") .IsRequ ...
- zoj 3809 枚举水题 (2014牡丹江网赛 A题)
题目大意:给出一列取样的几个山的高度点,求山峰有几个? Sample Input 291 3 2 4 6 3 2 3 151 2 3 4 5Sample Output 30 # include < ...
- JavaScript中变量的相互引用
http://www.jb51.net/article/23387.htm
- All Friends 极大团
搞懂了什么是团 什么是极大团 什么是最大团 极大团就是 不是任何团的真子集 最大团就是点数最多的极大团 这题就是求极大团的个数 用bk算法 #include <iostream> ...
- 配置https域名
https://help.aliyun.com/knowledge_detail/95505.html?spm=5176.11065259.1996646101.searchclickresult.6 ...