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:

  1. Don't Link
  2. Link SDK Assemblies
  3. 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的更多相关文章

  1. Xamarin.Android之简单的抽屉布局

    0x01 前言 相信对于用过Android版QQ的,应该都不会陌生它那个向右滑动的菜单(虽说我用的是Lumia) 今天就用Xamarin.Android实现个比较简单的抽屉布局.下面直接进正题. 0x ...

  2. Xamarin.Android 反复报 Please Download android_m2repository_rxx.zip 的解决办法

    我原来一直用的是老版本的 Xamarin , android_m2repository_rxx.zip 早已在 C:\Users\XXX\AppData\Local\Xamarin\Android.S ...

  3. Xamarin For Visual Studio 3.0.54.0 完整离线破解版(C# 开发Android、IOS工具 吾乐吧软件站分享)

    Xamarin For Visual Studio就是原本的Xamarin For Android 以及 Xamarin For iOS,最新版的已经把两个独立的插件合并为一个exe安装包了.为了区分 ...

  4. Xamarin Mono For Android 4.6.07004 完整离线安装破解版(C#开发Android、IOS工具)

      Xamarin是由Miguel de Icaza成立的一家新的独立公司,目的是给Mono一个继续奋斗的机会.Mono for Android (原名:MonoDroid)可以让开发人员使用 Mic ...

  5. Xamarin Mono 环境搭建(使用Visual Studio 2013 开发android 和 ios )

    本文主要介绍Xamarin结合VS2013来开发Android应用程序,主要会介绍Mono和Xamarin的关系,以及整个搭建环境的过程. 一.Mono和Xamarin介绍 1.Mono简介 Mono ...

  6. ComponentOne Xuni助力Xamarin开发者突破百万,快速开发Android、IOS Apps

    在微软Build 2015上,随着VS 2015的预览版发布,Xamrine免费版已经作为VS 2015跨平台移动解决方案的核心.与此同时,Xamarin官方也宣布其用户量达到百万之多.2011年7月 ...

  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 ...

  8. 张高兴的 Xamarin.Forms 开发笔记:为 Android 与 iOS 引入 UWP 风格的汉堡菜单 ( MasterDetailPage )

    所谓 UWP 样式的汉堡菜单,我曾在"张高兴的 UWP 开发笔记:汉堡菜单进阶"里说过,也就是使用 Segoe MDL2 Assets 字体作为左侧 Icon,并且左侧使用填充颜色 ...

  9. Xamarin.Form与Xamarin.Android或Xamarin.IOS的区别简述

    Xamarin.Form与Xamarin.Android或Xamarin.IOS的区别简述: 可能刚刚接触Xamarin的人来说,对于这个概念比较的模糊,认为这说的不都是同一个东西吗?事实并不是这样的 ...

随机推荐

  1. python之celery使用详解(二)

    前言 前面我们了解了celery的基本使用后,现在对其常用的对象和方法进行分析. Celery对象 核心的对象就是Celery了,初始化方法: class Celery(object): def __ ...

  2. VUE之搭建脚手架

    原文转自http://blog.csdn.net/Shiyaru1314/article/details/54963027 目录(?)[-] 1 安装之前需要检查是否已经安装NodeJS的环境 安装文 ...

  3. 阿里云url解析,发布web后去除url中的端口号

    归根结底就是80端口的使用,不是http的80 的 或 https的  都得加端口号 [问题描述] http://wisecores.wisers.com:8080/JsonProject/servl ...

  4. KnockoutJs学习笔记(八)

    with binding用于创建一个新的绑定环境(binding context),包含with binding的元素的所有子元素都将处于指定的object的环境限定内. 下面是一个简单的使用with ...

  5. .NetCore 分布式日志收集Exceptionless 在Windows下本地安装部署及应用实例

    自己安装时候遇到很多问题,接下来把这些问题写出来希望对大家有所帮助 搭建环境: 1.下载安装 java 8 SDK (不要安装最新的10.0) 并配置好环境变量(环境变量的配置就不做介绍了) 2.下载 ...

  6. PhoneGap学习地址 / PhoneGap API介绍:Events

    http://blog.csdn.net/phonegapcn 事件类型: backbutton deviceready menubutton pause resume searchbutton on ...

  7. IO知识点整理(四种基类的使用)

    一:介绍 1.两种基类 字节流 InputStream,OutputStream 字符流 Reader,Writer 二:字符流的基本方法(文字的处理比较常见) 1.Writer的API 2.File ...

  8. Java字符串跟ASCII码互转

    1.由于项目中遇到,在服务器端起的jar包程序,给前台发消息后,前段收到的消息出现乱码情况,所以采取在后才发消息前先把消息字符串转成ASCII码再发往前台,前台采取在收到后台消息先把ASCII码转成字 ...

  9. 网站截图工具EyeWitness

    网站截图工具EyeWitness   在网页分析和取证中,往往需要大批量的网站截图.Kali Linux提供了一款网站批量截图工具EyeWitness.该工具不仅支持网址列表文件,还支持Nmap和Ne ...

  10. bzoj 1455 可并堆+并查集

    一个堆和一个并查集对应,并且满足并查集中所有没有死的人等于堆中的人 /************************************************************** Pr ...